KEMBAR78
Polymorphism in Object-oriented Programming | PPTX
Polymorphism
Polymorphism
• Polymorphism is another 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
Polymorphism Types
Compile-Time Polymorphism
• Compile-Time Polymorphism 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
Function Overloading
• function overloading 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.
class Printer {
public:
void print(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
// ❌ This will 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
Summary
Aspect Description
Same function name Yes
Different params Yes – in number or type
Different return No – return type alone is not sufficient for overloading
Benefit Cleaner code and flexibility
Operator Overloading
• Operator Overloading 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.
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
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;
}
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;
}
Rules of Operator Overloading
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
Commonly Overloaded Operators in C++
Operator Typical Use Case
+ Add objects (e.g., vectors, complex numbers)
- Subtract objects
* Multiply objects
== Compare objects
<<, >> Input/output
[] Indexing
() Function-call operator
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
Run Time Polymorphism
• It is achieved by using a combination of :
• Function Overriding
• Virtual Functions
• Base Class Pointers or References to derived class objects
Function Overriding
• Real-Life Example: 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
Function Overriding
• Function Overriding 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.
Function Overriding
class baseClass {
public:
void display()
{
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.
• A virtual function 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.
•To make a function 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
Diff b/w virtual and 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.
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.
Function overriding with virtual 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;
}
};
Function overriding with virtual 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;
}
};
Function overriding with virtual function (source.cpp)
#include<iostream>
#include "Header.h"
using namespace std;
int main()
{
shape *obj1;
shape* obj2;
shape* obj3;
triangle tri_obj(10,20,30);
square sqr_obj(10, 20, 30);
circle crl_obj(10, 20, 30);
obj1 = &tri_obj;
obj2 = &sqr_obj;
obj3 = &crl_obj;
cout << obj1->area() << endl;
cout << obj2->area() << endl;
cout << obj3->area() << endl;
return 0;
}
Output
• 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.
• 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.
#include <iostream>
using namespace std;
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;
}
#include <iostream>
using namespace std;
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.
When Does Run-Time Binding 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.

Polymorphism in Object-oriented Programming

  • 1.
  • 2.
    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
  • 3.
  • 4.
    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
  • 14.
    Commonly Overloaded Operatorsin C++ Operator Typical Use Case + Add objects (e.g., vectors, complex numbers) - Subtract objects * Multiply objects == Compare objects <<, >> Input/output [] Indexing () Function-call operator
  • 15.
    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.
  • 19.
  • 20.
    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; } };
  • 27.
    Function overriding withvirtual function (source.cpp) #include<iostream> #include "Header.h" using namespace std; int main() { shape *obj1; shape* obj2; shape* obj3; triangle tri_obj(10,20,30); square sqr_obj(10, 20, 30); circle crl_obj(10, 20, 30); obj1 = &tri_obj; obj2 = &sqr_obj; obj3 = &crl_obj; cout << obj1->area() << endl; cout << obj2->area() << endl; cout << obj3->area() << endl; return 0; }
  • 28.
  • 29.
    • 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.