Polymorphism
• Polymorphism isanother fundamental principles of Object-Oriented Programming
(OOP)
• The term Polymorphism comes from the Greek words poly (meaning “many”) and
morph (meaning “forms”).
• It refers to the ability of one function, operator, or object to behave in different ways
depending on the context.
Imagine you're developing a Payment System for an e-commerce platform.
Customers can pay using:
• Credit Card
• Debit Card
• PayPal
• Cash on Delivery
Each payment method processes the payment differently, but they all follow a
common interface: makePayment().
Example
Compile-Time Polymorphism
• Compile-TimePolymorphism also known as Static Binding is a type of
polymorphism where the decision about which method or function to call is
made at compile time.
• Key Characteristics:
• Resolved at compile time
• Faster execution
• Implemented using:
• Function overloading
• Operator overloading
5.
Function Overloading
• functionoverloading allows multiple functions to have the same name with
different parameter lists (different number or types of parameters).
• Allows to define behavior for similar operations with different input types or
numbers.
• Real-Life Analogy:
Imagine a printer machine:
• If you give it a document, it prints a document.
• If you give it a photo, it prints a photo.
• If you give it a PDF, it prints a PDF.
• Even though the command is the same—print()—the behavior changes based on the
input.
• Basic Rules of Function Overloading
• Functions must differ by the number or type of parameters.
• Return type alone is not enough to overload a function.
6.
class Printer {
public:
voidprint(int num) {
cout << "Printing number: " << num << endl;
}
void print(double num) {
cout << "Printing decimal: " << num << endl;
}
void print(string text) {
cout << "Printing text: " << text << endl;
}
};
int main() {
Printer p;
p.print(10); // Calls print(int)
p.print(3.14); // Calls print(double)
p.print("Hello World"); // Calls print(string)
return 0;
}
#include <iostream>
using namespace std;
void print(int x) {
cout << "Integer: " << x << endl;
}
void print(int x, int y) {
cout << "Two Integers: " << x << ", " << y << endl;
}
int main() {
print(10);
print(10, 20);
return 0;
} Overloading with Different Number of Parameters
Overloading with Different Types of Parameters
Function Overloading
7.
// ❌ Thiswill cause an error
int add(int x)
{
return x;
}
double add(int x)
{
return (double)x;
}
This is not allowed because the compiler cannot differentiate based on
return type alone.
Function Overloading
8.
Summary
Aspect Description
Same functionname Yes
Different params Yes – in number or type
Different return No – return type alone is not sufficient for overloading
Benefit Cleaner code and flexibility
9.
Operator Overloading
• OperatorOverloading allows to redefine the meaning of operators (+, -, ==,
etc.) foruser-defined types like classes or structures.
• Purpose:
• Make class objects behave more like built-in types by giving intuitive meaning
to operators when used with objects.
For example:
a + b; // for integers
// If 'a' and 'b' are objects, we can define '+' to work meaningfully for them too.
10.
Syntax:
return_type operator op(arguments) {
// your logic here
}
• operator is a keyword.
• op is the operator being overloaded (+, -, etc.).
• This can be a member function or a friend function.
Operator Overloading
11.
Example 1: Overloading+ for a Complex Number Class
#include <iostream>
using namespace std;
class Complex {
float real, imag;
public:
Complex(float r = 0, float i = 0) {
real = r;
imag = i;
}
// Overloading + operator
Complex operator + (Complex c) {
complex c4(real + c.real, imag + c.imag);
return c4;
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
int main() {
Complex c1(3.5, 2.5), c2(1.5, 4.5);
Complex c3 = c1 + c2; // Uses overloaded +
c3.display(); // Output: 5 + 7i
return 0;
}
12.
Example 2: Overloading== Operator for a Student
Class
#include <iostream>
using namespace std;
class Student {
int rollNo;
string name;
public:
Student(int r, string n) {
rollNo = r;
name = n;
}
bool operator == (Student s) {
return (rollNo == s.rollNo && name == s.name);
}
};
int main() {
Student s1(1, "Ali"), s2(1, "Ali"), s3(2, "Ahmed");
if (s1 == s2)
cout << "Same student" << endl;
else
cout << "Different students" << endl;
return 0;
}
13.
Rules of OperatorOverloading
1 You can only overload existing operators.
2 At least one operand must be a user-defined type.
3 Some operators cannot be overloaded: ::, .*, ., sizeof, typeid.
4 You cannot change precedence or associativity.
5 You cannot change the number of operands.
6 When using binary operators overloaded through a member function, the left-hand
operand must be an object of the relevant class.
Binary operators, overloaded by a member function, take one explicit argument
7
8 Unary operators, overloaded by a friend function, take one argument(the object of the
relevant class)
9 Binary operators, overloaded by a friend function take two explicit arguments.
10 Unary operators, overloaded by a friend function, take one argument(the object of the
relevant class
Run Time Polymorphism
•Run Time Polymorphism occurs when the method to be called is
determined at run time, not at compile time.
• It is also known as dynamic binding or late binding
16.
Run Time Polymorphism
•It is achieved by using a combination of :
• Function Overriding
• Virtual Functions
• Base Class Pointers or References to derived class objects
17.
Function Overriding
• Real-LifeExample: Patient Consultation System
• A generic Doctor class with a function consult(). This represents a generic
consultation process.
• A Dentist specializes in teeth-related consultations
• A Cardiologist handles heart-related issues
18.
Function Overriding
• FunctionOverriding is also known as method overriding
• Function overriding occurs
• when a derived class provides a specific implementation of a function that is
already defined in its base class, using the same name, return type, and
parameters.
class baseClass {
public:
voiddisplay()
{
cout << " Base Class
Execute " << endl;
}
};
using namespace std;
int main()
{
derivedClass obj;
obj.display();
return 0;
}
Function Overriding class derivedClass: public baseClass
{
public:
void display()
{
cout << " Derived Class Execute and
this derive class override the
function of base class " << endl;
}
};
• There must be inheritance (base and derived class).
• The signature (name and parameters) of the function must be exactly the
same in both base and derived classes.
21.
• A virtualfunction is a member function in a base class that you
expect to override in derived classes.
• It allows run-time polymorphism, meaning the function to call is
decided at runtime based on the actual type of the object.
Virtual Function
• Allows one interface to be used for different underlying types.
• You can call a method on a base class reference, and the correct
derived class version is executed.
22.
•To make afunction virtual, the virtual keyword must precede the
function declaration in the base class.
•The redefinition of the function in any derived class does not require a
second use of the virtual keyword.
Virtual Function
23.
Diff b/w virtualand non-virtual member Functions
•The difference between a non-virtual member function and a virtual
member function is,
• the non-virtual member functions are resolved at compile time.
• Whereas the virtual member functions are resolved at run-time.
• The concept of pointers to objects is prior to knowing before
implementing the virtual function.
24.
Pointer to Object/ Object Pointer
•A pointer pointing to a class object is called an object pointer.
•Synatx: Class name *variableName
•Example: Shape *optr; // in the this declaration optr is a pointer to an object
of class Shape.
•To refer directly to a member of an object pointed by a pointer we can use
the arrow operator (- >) instead of dot ( . )
•Object pointers are useful in creating objects at run time and public members
of the class can be accessible by object pointers.
25.
Function overriding withvirtual function
#include <iostream>
using namespace std;
class shape
{
protected:
int len, wid, radius;
public:
virtual int area()
{
return 0;
}
};
class triangle:public shape {
public:
triangle(int l, int w, int r)
{
len = l;
wid = w;
radius = r;
}
int area()
{
cout << " Triangle of Area: ";
return 0.5 * len * wid;
}
};
26.
Function overriding withvirtual function
class circle :public shape {
public:
circle(int l, int w, int r)
{
len = l;
wid = w;
radius = r;
}
int area()
{
cout << " Circle of Area: ";
return 3.14 * radius * radius ;
}
};
class square :public shape {
public:
square(int l, int w, int r)
{
len = l;
wid = w;
radius = r;
}
int area()
{
cout << " Square of Area: ";
return len * wid;
}
};
• In compile-timebinding, the decision of which function to call is
made at compile time, based on the type of the pointer/reference,
not the object it points to.
• Run-time polymorphism allows you to decide which function to call
at runtime depending on the actual type of the object that a pointer
or reference refers to — not the type of the pointer or reference
itself.
30.
#include <iostream>
using namespacestd;
class Animal {
public:
virtual void sound() { // Virtual function
cout << "Some animal sound" << endl;
}
};
class Dog : public Animal {
public:
void sound() override {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
void sound() override {
cout << "Meow!" << endl;
}
};
int main() {
Animal* a; // Base class pointer
Dog d;
Cat c;
a = &d;
a->sound(); // Output: Woof! (run-time decision)
a = &c;
a->sound(); // Output: Meow! (run-time decision)
return 0;
}
31.
#include <iostream>
using namespacestd;
class Animal {
public:
void sound() { // Virtual function
cout << "Some animal sound" << endl;
}
};
class Dog : public Animal {
public:
void sound() override {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
void sound() override {
cout << "Meow!" << endl;
}
};
int main() {
Animal* a; // Base class pointer
Dog d;
Cat c;
a = &d;
a->sound(); // Output: Some animal sound
(compile-time decision)
a = &c;
a->sound(); // Output: Meow! (run-time decision)
return 0;
In compile-time binding, the decision of which function to
call is made at compile time, based on the type of the
pointer/reference, not the object it points to.
If you remove the virtual keyword, then:
without the virtual keyword, C++ uses
compile-time (or static) binding
Even if a points to a Dog, the base class function will
be called.
32.
When Does Run-TimeBinding Happen?
Only when:
•The function in the base class is marked as virtual.
•The function is overridden in the derived class.
•The call is made using a base class pointer or
reference.