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.