Chapter 7
Polymorphism
1
Polymorphism
• Polymorphism—the same word or phrase
can be mean different things in different
contexts
• Greek term polymorphos means “having many
forms.”
• For example:
– In OOP, two or more classes could each have a
method called output
– Each output method would do the right thing
for the class that it was in.
– One output might display a number whereas a 2
different one might display a name.
Overriding vs. Overloading
• Overloading refers to methods of the
same class with the same name but
different signatures or return types.
• Overriding refers to methods of different
classes with the same name, signatures
and return types. The overriden method
appears in a subclass.
3
Overloading Functions
4
Overloaded Functions
• The operation of one function depends on the argument
passed to it.
– Example: Fly(), Fly(low), Fly(150)
• Some languages, like C++, permit the programmer to
overload function names
• For Example:
int square(int x) {
return x*x;
}
double square(double x) {
return x*x;
}
5
Overriding Functions
6
Virtual Functions
• A virtual function is a member function
– declared within a base class
– redefined by a derived class (i.e. overriding)
• A virtual member function in a base class
expects to be overridden in a derived class
• The keyword virtual is used to designate a
member function as virtual.
• It can be used to support run-time
polymorphism.
• Used to support polymorphism with pointers and
references
7
Virtual Functions (cont’d)
• In derived class – redefined and the
function signature must match the
original function (in the base class).
• keyword virtual not needed in
derived class (but can be specified if
the programmer wants).
• The “virtual”-ity of the member
function continues along the
inheritance chain.
• polymorphic class - class that
contains a virtual function
8
Virtual Functions – Example 1
class base { void main() {
public: base b1;
virtual void show() { b1.show(); // base - (s.b.)
cout << “base\n”; derived d1;
} d1.show(); // derived – (s.b.)
};
base *pb = &b1;
class derived : public base { pb->show(); // base - (d.b.)
public: pb = &d1;
void show() { pb->show(); // derived (d.b.)
cout << “derived\n”; }
}
}; Here,
s.b. = static binding
d.b. = dynamic binding
9
Virtual Functions – Example 2
class base { class d2 : public base {
public: public:
virtual void show() { void show() {
cout << “base\n”; cout << “derived-2\n”;
} }
}; };
class d1 : public base { void main() {
public: base *pb; d1 od1; d2 od2;
void show() { int n;
cout << “derived-1\n”; cin >> n;
} if (n % 2) pb = &od1;
}; else pb = &od2;
pb->show(); // guess what ??
Run-time polymorphism } 10
Virtual Functions – Example 3
• Base Class Main function
class base { int main() {
public: base ob(10), *p;
int i; derived d_ob(10);
base (int x) { i = x; }
virtual void func() {cout << i; } p = &ob;
}; p->func(); // use base’s func()
p = &d_ob;
• Derived Class p->func(); // use derived’s
class derived : public base { func()
public: }
derived (int x) : base (x) {}
// The keyword virtual is not
needed.
void func() {cout << i * i; }
11
};
Non-Virtual Destructor
class base { void main() {
public: base *p = new derived;
~base() { delete p;
cout << “destructing base\n”; }
}
};
Output:
class derived : public base { destructing base
public:
~derived() {
cout << “destructing derived\n”;
}
};
Using non-virtual destructor
12
Virtual Destructors
• Constructors cannot be virtual, but
destructors can be virtual.
• It ensures that the derived class
destructor is called when a base
class pointer is used while deleting
a dynamically created derived class
object. 13
Virtual Destructors – Example
class base { void main() {
public: base *p = new derived;
virtual ~base() { delete p;
cout << “destructing base\n”; }
}
}; Output:
destructing derived
class derived : public base { destructing base
public:
~derived() {
cout << “destructing derived\n”;
}
};
Using virtual destructor 14
Pure Virtual Functions – Abstract
Classes
• If we want to omit the body of a virtual function in a
base class, we can use pure virtual functions.
• A pure virtual function has no definition relative to the
base class.
• Only the function’s prototype is included.
• General form:
virtual type func-name(paremeter-list) = 0
• It makes a class an abstract class.
– We cannot create any objects of such classes.
• It forces derived classes to override it.
– Otherwise they become abstract too. 15
Pure Virtual Functions (contd.)
• Pure virtual function
– Helps to guarantee that a derived class will
provide its own redefinition.
• We can still create a pointer to an
abstract class
– Because it is at the heart of run-time
polymorphism
• When a virtual function is inherited, so is its
virtual nature.
• We can continue to override virtual
functions along the inheritance hierarchy.
16
Example 1
class rectangle : public area {
class area { public:
public: // function overriding
double dim1, dim2; double getarea() {
area(double x, double y) return dim1 * dim2;
{dim1 = x; dim2 = y;} }
// pure virtual function };
virtual double getarea() = 0;
}; class triangle : public area {
public:
// function overriding
double getarea() {
return 0.5 * dim1 * dim2;
}
};
17
Example 2
• Example : Shape
– Shape s; // “Shapeless shape”
– Shape makes sense only as a base of some classes
derived from it.
– Serves as a “category”
– Hence instantiation of such a class must be
prevented
class Shape //Abstract • A class with one or more pure
{ virtual functions is an Abstract
public : Class
//Pure virtual Function
virtual void draw() = 0; • Objects of abstract class can’t be
} created
Shape s; // error : variable of an abstract class
18
Example 2 (cont’d)
Shape
virtual void draw()
Circle Triangle
public void draw() public void draw()
19
Example 2 (cont’d)
• A pure virtual function not defined in the
derived class remains a pure virtual function.
• Hence derived class also becomes abstract
class Circle : public Shape { //No draw() - Abstract
public :
void print(){
cout << “I am a circle” << endl;
}
class Rectangle : public Shape {
public :
void draw(){ // Override Shape::draw()
cout << “Drawing Rectangle” << endl;
}
Rectangle r; // Valid
Circle c; // error : variable of an abstract class
Abstract Classes and Methods
• Purpose of an abstract class
– Declare common attributes …
– Declare common behaviors of classes in a
class hierarchy
• Contains one or more abstract methods
– Subclasses must override
• Instance variables, concrete methods of
abstract class
– subject to normal rules of inheritance
21
Abstract Classes
• Classes that are too general to create
real objects
• Used only as abstract superclasses for
concrete subclasses and to declare
reference variables
• Many inheritance hierarchies have
abstract superclasses occupying the top
few levels
22