Class 10 | Polymorphism | C++ Notes

Polymorphism

Polymorphism is the ability of a message to be displayed in more than one form.

Polymorphism is the combination of “poly” + “morphism”, which means many forms.

A real-life example of polymorphism is a person who can have different characteristics at the same time.

For example, a man can simultaneously be:

  • A father
  • A husband
  • An employee

The same person exhibits different behavior in different situations. This is called polymorphism.

Advantages of Polymorphism

  1. It helps programmers reuse code and classes once written, which is called code reusability.
  2. A single function name can be used to store multiple data types.
  3. It is used to extend the functionality of a class.

Types of Polymorphism

There are two types of polymorphism:

  1. Compile-Time Polymorphism
  2. Runtime Polymorphism

1. Compile-Time Polymorphism

The polymorphism that can be achieved using function overloading or operator overloading at compile time is called Compile-Time Polymorphism.

Function Overloading

When there are multiple functions with the same name but different parameters, the functions are said to be overloaded.

The process of having two or more functions with the same name but different parameters is called Function Overloading.

A function can be overloaded by:

  1. Changing the number of arguments.
  2. Changing the type of arguments.

Syntax:

Void fun() {}

Void fun(int, int) {}

Example 1: Function Overloading

#include <iostream>

class Add {

public:

int sum(int num1, int num2) {

return num1 + num2;

}

int sum(int num1, int num2, int num3) {

return num1 + num2 + num3;

}

};

int main() {

Add obj;

cout << “Output: ” << obj.sum(10, 20) << “\n”;

cout << “Output: ” << obj.sum(11, 22, 33) << “\n”;

return 0;

}

Example 2: Function Overloading

#include <iostream>

using namespace std;

class Geeks {

public:

void func(int x)

{

cout << “value of x is ” << x << endl;

}

void func(double x)

{

cout << “value of x is ” << x << endl;

}

void func(int x, int y)

{

cout << “value of x and y is ” << x << “, ” << y << endl;

}

};

int main()

{

Geeks obj1;

obj1.func(7);

obj1.func(9.132);

obj1.func(85, 64);

return 0;

}

Operator Overloading

Operator Overloading is a compile-time polymorphism in which an operator is overloaded to provide special meaning to a user-defined data type.

C++ has the ability to provide operators with special meanings for different data types. This ability is known as operator overloading.

The advantage of operator overloading is that it allows different operations to be performed using the same operator.

For example, the addition operator (+) can be used with strings to concatenate two strings.

When the + operator is placed between integer operands, it adds them.

When the same operator is placed between string operands, it concatenates them.

Example

#include <iostream>

using namespace std;

int main() {

int sum = 25 + 35; // used for addition

cout << “addition” << sum;

string s1 = “we are members”;

string s2 = “of Nexu cornerl”;

string s3 = s1 + s2;

cout << s3 << endl;

return 0;

}

Operators That Cannot Be Overloaded

The following C++ operators cannot be overloaded:

  1. Scope Resolution Operator ::
  2. Dot Operator .
  3. Size of Operator
  4. Ternary Operator ?:
  5. Pointer-to-member selection operator .*

Declaration of Operator Overloading

Syntax:

Return_type/class_name operator symbol(argument_list)

{

// body of statements

}

Types of Operator Overloading

There are two types:

  1. Unary Operator Overloading
  2. Binary Operator Overloading

1. Unary Operator Overloading

An operator that contains only one operand is called a Unary Operator.

The increment operator ++ and decrement operator -- are examples of unary operators.

Example: Overloading ++ as Prefix

#include <iostream>

using namespace std;

class Count {

private:

int value;

public:

Count() {

Value = 5;

}

void operator ++ () {

++value;

}

void display() {

cout << “Count: ” << value << endl;

}

};

int main() {

Count count1;

Count1.display();

++count1;

count1.display();

return 0;

}

C++ Program to Show — Operator Overloading

#include <iostream>

using namespace std;

class Distance {

public:

int feet, inch;

Distance(int f, int i)

{

feet = f;

inch = i;

}

void operator–()

{

feet–;

inch–;

cout << “\nFeet & Inches(Decrement): ” << feet << “‘” << inch;

}

};

int main()

{

Distance d1(8, 9);

–d1;

return 0;

}

2. Binary Operator Overloading

An operator that contains two operands is called a Binary Operator.

Arithmetic, relational, and logical operators are examples of binary operators.

Program to Demonstrate Binary Operator Overloading

#include <iostream>

using namespace std;

class Complex {

private:

int real, imag;

public:

Complex(int r, int i)

{

real = r;

imag = i;

}

Complex operator + (Complex obj)

{

Complex res;

res.real = real + obj.real;

res.imag = imag + obj.imag;

return res;

}

void print() {

cout << real << ” + i” << imag << ‘\n’;

}

};

int main()

{

Complex c1(10, 5), c2(2, 4);

c3 = c1 + c2;

c3.print();

return 0;

}

Example 2: Binary Operator Overloading

#include <iostream>

using namespace std;

class Distance {

public:

int feet, inch;

Distance()

{

feet = 0;

inch = 0;

}

Distance(int f, int i)

{

feet = f;

inch = i;

}

Distance operator+(Distance& d2)

{

Distance d3;

d3.feet = feet + d2.feet;

d3.inch = inch + d2.inch;

return d3;

}

};

int main()

{

Distance d1(8, 9);

Distance d2(10, 2);

Distance d3;

d3 = d1 + d2;

cout << “\nTotal Feet & Inches: ” << d3.feet << ” ‘ ” << d3.inch;

return 0;

}

Example: Overloading Operator to Add Objects

#include <iostream>

using namespace std;

class Complex

{

int x, y;

public:

void input()

{

cout << ” Input two complex number: ” << endl;

cin >> x >> y;

}

Complex operator + (Complex obj)

{

Complex A;

A.x = x + obj.x;

A.y = y + obj.y;

return A;

}

void print()

{

cout << x << ” + ” << y << “i” << “\n”;

}

int main()

{

Complex x1, y1, sum;

y1.input();

sum = x1 + y1;

return 0;

}

2. Run-Time Polymorphism

The polymorphism that can be achieved using Function Overriding and Virtual Functions at runtime is called Run-Time Polymorphism.

It is also known as:

  • Late Binding
  • Dynamic Polymorphism

In runtime polymorphism, the function call is resolved at runtime.

Function Overriding

When the base class and derived class have the same member function with the same name and same parameters, it is called Function Overriding.

It occurs when a derived class provides its own definition of a member function that already exists in the base class.

Example 1: Function Overriding

#include <iostream>

using namespace std;

class Parent {

public:

void NepalEnotes_Print()

{

cout << “Base Function” << endl;

}

};

class Child : public Parent {

public:

void NepalEnotes_Print()

{

cout << “Derived Function” << endl;

Parent::NepalEnotes_Print();

}

};

int main()

{

Child Child_Derived;

Child_Derived.NepalEnotes_Print();

return 0;

}

Example 2: Function Overriding

#include <iostream>

using namespace std;

class Car

{

public:

void Start()

{

cout << “Car Started” << endl;

}

void Stop()

{

cout << “Car Stopped” << endl;

}

};

class Innova : public Car

{

public:

void Start()

{

cout << “Innova Started” << endl;

}

void Stop()

{

cout << “Innova Stopped” << endl;

}

};

class Swift : public Car

{

public:

void Start()

{

cout << “Swift Started” << endl;

}

void Stop()

{

cout << “Swift Stopped” << endl;

}

int main()

{

Swift s;

s.start();

s.stop();

return 0;

}

Virtual Function

A Virtual Function is a member function that is declared in the base class using the keyword virtual and is re-defined or overridden in the derived class.

Key Points About Virtual Functions

  1. Virtual functions are dynamic in nature.
  2. They are defined by inserting the keyword virtual inside a base class.
  3. They are declared in the base class and overridden in the child class.
  4. A virtual function is called during runtime.
  5. It is used to achieve runtime polymorphism.

C++ Program to Demonstrate Virtual Function

#include <iostream>

using namespace std;

class GFG_Base {

public:

// Virtual function

virtual void display() {

cout << “Called virtual Base Class function” << “\n\n”;

}

void print()

{

cout << “Called GFG_Base print function” << “\n\n”;

}

};

class GFG_Child : public GFG_Base {

public:

void display()

{

cout << “Called GFG_Child Display Function” << “\n\n”;

}

void print()

{

cout << “Called GFG_Child print Function” << “\n\n”;

}

};

int main()

{

GFG_Base* base;

GFG_Child child;

base = &child;

base->display();

base->print();

}

Example 2: Virtual Function

#include <iostream>

using namespace std;

class Car {

public:

virtual void Start()

{

cout << “Car Started” << endl;

}

virtual void Stop()

{

cout << “Car Stopped” << endl;

}

};

class Innova : public Car

{

public:

void Start()

{

cout << “Innova Started” << endl;

}

void Stop()

{

cout << “Innova Stopped” << endl;

}

};

class Swift : public Car

{

public:

void Start()

{

cout << “Swift Started” << endl;

}

void Stop()

{

cout << “Swift Stopped” << endl;

}

};

int main() {

Car *c;

c->Start();

c->Stop();

Car = &Innova;

c->Start();

c->Stop();

Car = &swift;

c->Start();

c->Stop();

return 0;

}

Pure Virtual Function

A Pure Virtual Function is a virtual function that has no definition or implementation.

It starts with the virtual keyword and is declared by assigning 0.

A pure virtual function is implemented by classes that are derived from an abstract class.

Syntax:

Virtual return_type function_name() = 0;

Abstract Class

A class that contains at least one pure virtual function is called an Abstract Class.

An abstract class is designed specifically to be used as a base class.

No object of an abstract class can be created.

It allows a base class to provide only an interface for its derived classes.

We can have pointers and references of an abstract class type.

If the pure virtual function is not overridden in a derived class, then the derived class also becomes an abstract class.

Example: Abstract Class

#include <iostream>

using namespace std;

class database {

public:

virtual void getName() = 0;

};

class Manager : public database {

public:

void getName() {

cout << “this is the manger class:\n”;

}

};

class accountant : public database {

public:

void getName() {

cout << “this is the accountant class:\n”;

}

};

class customer : public database {

public:

void getName() {

cout << “this is the customer class:\n”;

}

};

int main()

{

Manager m;

database *d;

d = &m;

d->getName();

}

C++ Program to Illustrate Abstract Class and Virtual Functions

#include <iostream>

using namespace std;

class Base {

int x;

public:

virtual void fun() = 0;

int getX() {

return x;

}

};

class Derived : public Base {

int y;

public:

void fun() {

cout << “fun() called”;

}

};

int main()

{

Derived d;

d.fun();

return 0;

}

Static Binding

When the compiler gets all the information required to call a function or all the values of variables during compile time, it is called Static Binding.

It is also called Early Binding.

Static binding enhances the speed of execution of a program.

Examples of static binding include:

  • Function Overloading
  • Operator Overloading

Dynamic Binding

Calling a function or assigning a value to a variable at runtime is called Dynamic Binding.

It is also called Late Binding.

Dynamic binding makes program execution flexible because it allows the value to be assigned and the function to be called at runtime.

However, execution can be slower compared to static binding.

Examples of dynamic binding include:

  • Function Overriding
  • Virtual Functions

Discussion

Share a helpful question, idea, or explanation with other students.

Leave a Comment

Write a clear question, answer, or helpful explanation.
Your email will not be published.

Download Our Offline App

Study class-wise notes even when internet is not available. Get the app from Play Store.

Nepal eNotes offline app preview
Get it on Google Play