OOP: Polymorphism (1)
Slides version: lecture11_slides.html Website version: lecture11.html
- What is Polymorphism? and Why do we need it?
- Example: Bus, Car, and Truck.
- Polymorphism Types
- Compile time
- Run time
- Virtual Function
- Syntax:
virtual
member function & object pointer - Example:
- Syntax:
- Example 1: Integer & Real
- Example 2: Complex Number
- Example 3: Integer & Real & Complex Number
- Pratices
What is Polymorphism? and Why do we need it?
Ref: https://www.geeksforgeeks.org/polymorphism-in-c/
The word polymorphism means having many forms. In simple words, we can define polymorphism as the ability of a message to be displayed in more than one form. A real-life example of polymorphism, a person at the same time can have different characteristics. Like a man at the same time is a father, a husband, an employee. So the same person posses different behavior in different situations. This is called polymorphism.
Example: Bus, Car, and Truck
- A Bus:
- has 4 wheels
- has 20 seats
- has 2 doors
- has 20 windows
- A Car:
- has 4 wheels
- has 4 seats
- has 4 doors
- has 4 windows
- A Truck:
- has 6 wheels
- has 2 seats
- has 2 doors
- has 2 windows
function overloading
#include <iostream>
using namespace std;
class Vehicle
{
public:
void wheels() {}
void seats() {}
void doors() {}
void windows() {}
};
class Bus : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 4" << endl;
}
void seats()
{
cout << "Seats: 20" << endl;
}
void doors()
{
cout << "Doors: 2" << endl;
}
void windows()
{
cout << "Windows: 20" << endl;
}
};
class Car : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 4" << endl;
}
void seats()
{
cout << "Seats: 4" << endl;
}
void doors()
{
cout << "Doors: 4" << endl;
}
void windows()
{
cout << "Windows: 4" << endl;
}
};
class Truck : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 6" << endl;
}
void seats()
{
cout << "Seats: 2" << endl;
}
void doors()
{
cout << "Doors: 2" << endl;
}
void windows()
{
cout << "Windows: 2" << endl;
}
};
int main()
{
Bus b;
Car c;
Truck t;
b.wheels();
b.seats();
b.doors();
b.windows();
c.wheels();
c.seats();
c.doors();
c.windows();
t.wheels();
t.seats();
t.doors();
t.windows();
}
Output:
$ ./a.out
Wheels: 4
Seats: 20
Doors: 2
Windows: 20
Wheels: 4
Seats: 4
Doors: 4
Windows: 4
Wheels: 6
Seats: 2
Doors: 2
Windows: 2
virtual
member function
#include <iostream>
using namespace std;
class Vehicle
{
public:
virtual void wheels() {}
virtual void seats() {}
virtual void doors() {}
virtual void windows() {}
};
class Bus : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 4" << endl;
}
void seats()
{
cout << "Seats: 20" << endl;
}
void doors()
{
cout << "Doors: 2" << endl;
}
void windows()
{
cout << "Windows: 20" << endl;
}
};
class Car : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 4" << endl;
}
void seats()
{
cout << "Seats: 4" << endl;
}
void doors()
{
cout << "Doors: 4" << endl;
}
void windows()
{
cout << "Windows: 4" << endl;
}
};
class Truck : public Vehicle
{
public:
void wheels()
{
cout << "Wheels: 6" << endl;
}
void seats()
{
cout << "Seats: 2" << endl;
}
void doors()
{
cout << "Doors: 2" << endl;
}
void windows()
{
cout << "Windows: 2" << endl;
}
};
int main()
{
Vehicle *v[3]; // array of pointers to Vehicle
// used for polymorphism
v[0] = new Bus; // dynamically allocate Bus
v[1] = new Car; // dynamically allocate Car
v[2] = new Truck; // dynamically allocate Truck
for (int i = 0; i < 3; i++)
{
v[i]->wheels();
v[i]->seats();
v[i]->doors();
v[i]->windows();
}
for (int i = 0; i < 3; i++)
{
delete v[i];
}
}
Output:
$ ./a.out
Wheels: 4
Seats: 20
Doors: 2
Windows: 20
Wheels: 4
Seats: 4
Doors: 4
Windows: 4
Wheels: 6
Seats: 2
Doors: 2
Windows: 2
Polymorphism Types
- In C++ polymorphism is mainly divided into two types:
- Compile time Polymorphism
- Runtime Polymorphism
Compile time Polymorphism (Function/Operator Overloading)
// C++ program for function overloading
#include <iostream>
using namespace std;
class Geeks
{
public:
// function with 1 int parameter
void func(int x)
{
cout << "value of x is " << x << endl;
}
// function with same name but 1 double parameter
void func(double x)
{
cout << "value of x is " << x << endl;
}
// function with same name and 2 int parameters
void func(int x, int y)
{
cout << "value of x and y is " << x << ", " << y << endl;
}
};
int main()
{
Geeks obj1;
// Which function is called will depend on the parameters passed
// The first 'func' is called
obj1.func(7);
// The second 'func' is called
obj1.func(9.132);
// The third 'func' is called
obj1.func(85, 64);
return 0;
}
Runtime Polymorphism (Virtual Function with object pointer)
// C++ program for function overriding
#include <iostream>
using namespace std;
class base
{
public:
virtual void print()
{
cout << "print base class" << endl;
}
void show()
{
cout << "show base class" << endl;
}
};
class derived : public base
{
public:
void print() // print () is already virtual function in derived class,
// we could also declared as virtual void print () explicitly
{
cout << "print derived class" << endl;
}
void show()
{
cout << "show derived class" << endl;
}
};
// main function
int main()
{
base *bptr;
derived d;
bptr = &d;
// virtual function, binded at runtime (Runtime polymorphism)
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}
Virtual Function
Ref: https://www.geeksforgeeks.org/virtual-functions-and-runtime-polymorphism-in-c-set-1-introduction/
A virtual function is a member function which is declared in the base class using the keyword
virtual
and is re-defined (Overriden) by the derived class.
Syntax: virtual
member function & object pointer
class base
{
public:
virtual void a() {} // virtual function
};
class derived : public base
{
public:
void a() {} // non-virtual function, overridden by derived class
};
int main()
{
base *b_ptr;
derived d;
b_ptr = &d; // object pointer of derived class
// virtual function, binded at runtime (Runtime polymorphism)
b_ptr->a();
return 0;
}
Example 1:
// C++ program for function overriding
#include <iostream>
using namespace std;
class base
{
public:
virtual void print()
{
cout << "print base class" << endl;
}
void show()
{
cout << "show base class" << endl;
}
};
class derived : public base
{
public:
void print() // print () is already virtual function in derived class,
// we could also declared as virtual void print () explicitly
{
cout << "print derived class" << endl;
}
void show()
{
cout << "show derived class" << endl;
}
};
// main function
int main()
{
base *bptr;
derived d;
bptr = &d;
// virtual function, binded at runtime (Runtime polymorphism)
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}
Example 2:
class Employee
{
public:
virtual void raiseSalary()
{
/* common raise salary code */
}
virtual void promote()
{
/* common promote code */
}
};
class Manager : public Employee
{
virtual void raiseSalary()
{
/* Manager specific raise salary code, may contain
increment of manager specific incentives */
}
virtual void promote()
{
/* Manager specific promote */
}
};
// Similarly, there may be other types of employees
// We need a very simple function
// to increment the salary of all employees
// Note that emp[] is an array of pointers
// and actual pointed objects can
// be any type of employees.
// This function should ideally
// be in a class like Organization,
// we have made it global to keep things simple
void globalRaiseSalary(Employee *emp[], int n)
{
for (int i = 0; i < n; i++)
{
// Polymorphic Call: Calls raiseSalary()
// according to the actual object, not
// according to the type of pointer
emp[i]->raiseSalary();
}
}
Example 1: Integer & Real [Source]
Example 2: Complex Number [Source]
Example 3: Integer & Real & Complex Number [Source]
Pratices
-
Design a class hierarchy for Fruit.
- Contains: Grape, Apple, Orange
- Implement with based class
Fruit
- Use
virtual
function to provide universalprint()
,color()
functions
-
Design a class hierarchy for Quadrilateral.
- Contains: Square, Rectangle, Rhombus, Parallelogram
- Implement with based class
Quadrilateral
- Use
virtual
function to provide universalprint()
,area()
functions