You are on page 1of 33

OBJECT-ORIENTED

PROGRAMMING
(OOP)
o Type Compatibility in Inheritance Hierarchies

o Polymorphism and Virtual Member Functions

TYPE COMPATIBILITY IN INHERITANCE
HIERARCHIES
Classes in a program may be part of an inheritance
hierarchy
Classes lower in the hierarchy are special cases of
those up higher
Animal
Cat Dog
Poodle
TYPE COMPATIBILITY IN INHERITANCE
HIERARCHIES
A pointer to a derived class can be assigned to a
pointer to a base class

A base class pointer can point to derived class
objects
Animal *pA = new Cat;

Assigning a base class pointer to a derived class
pointer requires a cast
Animal *pA = new Cat;
Cat *pC;
pC = static_cast<Cat *>(pA);

USING BASE CLASS POINTERS
A base class pointer pointing to a derived class is
not aware of the existence of the derived class
members
So, the following is an error:

Person *pPerson = new Faculty(Dr. X, math);
pPerson->setDepartment(BIOLOGY); ERROR!

USING BASE CLASS POINTERS
To make the compiler aware of that a base class
pointer is actually pointing to its derived class, we
need to use a type cast. The following is ok:

static_cast<Faculty *>pPerson->setDepartment(BIOLOGY);

POLYMORPHISM AN INTRODUCTION
Definition
the quality or state of being able to assume different forms -
Webster
Polymorphism: from the Greek having multiple forms
In programming languages, the ability to assign a different meaning or
usage to something in different contexts
An essential feature of an OO Language
It builds upon Inheritance
Allows run-time interpretation of object type for a
given class hierarchy
Also Known as Late Binding
Implemented in C++ using virtual functions


POLYMORPHISM AND VIRTUAL MEMBER
FUNCTIONS
Polymorphic code: Code that behaves differently
when it acts on objects of different types

Virtual Member Function: The C++ mechanism for
achieving polymorphism

POLYMORPHISM
Consider the Animal, Cat, Dog hierarchy where
each class has its own version of the member
function id()

Animal
Cat Dog
Poodle
POLYMORPHISM
class Animal{
public: void id()
{cout << "animal";}
};
class Cat : public Animal
{
public: void id(){cout << "cat";}
};
class Dog : public Animal
{
public: void id(){cout << "dog";}
}

POLYMORPHISM
Consider the collection of different Animal objects
Animal *pA[] = {new Animal, new Dog,
new Cat};
and accompanying code
for(int k=0; k<3; k++)
pA[k]->id();

Prints: animal animal animal, ignoring the
more specific versions of id() in Dog and Cat

POLYMORPHISM
Preceding code is not polymorphic: it behaves the
same way even though Animal, Dog and Cat have
different types and different id() member functions

Polymorphic code would have printed "animal
dog cat" instead of "animal animal animal"

POLYMORPHISM
The code is not polymorphic because in the
expression
pA[k]->id()
the compiler sees only the type of the
pointer pA[k]: it is pointing to Animal
Compiler does not see type of actual object
pointed to, which may be Animal, or Dog,
or Cat
Such type information is only available at run
time because it depends on the value k!

VIRTUAL FUNCTIONS
Declaring a function virtual will make the
compiler check the type of each object to see if it
contains a more specific version of the virtual
function

VIRTUAL FUNCTIONS
If the member functions id()are declared virtual,
the code
Animal *pA[] = {new Animal,
new Dog,new Cat};
for(int k=0; k<3; k++)
pA[k]->id();
will print animal dog cat
VIRTUAL FUNCTIONS
How to declare a member function virtual:
class Animal{
public:
virtual void id(){cout << "animal";}
};
class Cat : public Animal{
public:
virtual void id(){cout << "cat";}
};
class Dog : public Animal{
public:
virtual void id(){cout << "dog";}
};

FUNCTION BINDING
In pA[k]->id(), Compiler must choose which
version of id() to use: There are different versions
in the Animal, Dog, and Cat classes
Function binding is the process of determining
which function definition to use for a particular
function call
The alternatives are static and dynamic binding

STATIC BINDING
Static binding chooses the function in the class of
the base class pointer, ignoring any versions in the
class of the object actually pointed to
Static binding is done at compile time
Static binding is very efficient

DYNAMIC BINDING
Dynamic Binding determines the function to be
invoked at execution time
Can look at the actual class of the object pointed to
and choose the most specific version of the function
Dynamic binding is used to bind virtual functions
More flexible, less efficient than static binding

A virtual member is a member function that can be redefined
in a derived class, while preserving its calling properties
through references. The syntax for a function to become
virtual is to precede its declaration with the virtual keyword:

// virtual members
#include <iostream>
using namespace std;

class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area ()
{ return 0; }
};

class Rectangle: public Polygon
{
public:
int area ()
{ return width * height; }
};

class Triangle: public Polygon {
public:
int area ()
{ return (width * height / 2); }
};
int main ()
{
Rectangle rect;
Triangle trgl;
Polygon poly;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
Polygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
cout << ppoly3->area() << '\n';
return 0;
}

The member function area has been declared
as virtual in the base class because it is later
redefined in each of the derived classes. Non-
virtual members can also be redefined in derived
classes, but non-virtual members of derived classes
cannot be accessed through a reference of the
base class: i.e., if virtual is removed from the
declaration of area in the example above, all three
calls to area would return zero, because in all
cases, the version of the base class would have
been called instead
A class that declares or inherits a virtual function is
called a polymorphic class
ABSTRACT CLASS
Abstract Class is a class which contains at least
one Pure Virtual Function in it

Abstract classes are used to provide an interface
for its sub classes.

Classes inheriting from Abstract class must provide
definition for pure virtual function otherwise they will
also become Abstract class.
CHARACTERISTICS OF ABSTRACT CLASS
Abstract class cannot be instantiated, but pointer of
the abstract class can be created.

Abstract class can have normal functions and
variable along with pure virtual function.

Classes inheriting an abstract class must
implement all pure virtual function, or else they will
become abstract too.

PURE VIRTUAL FUNCTIONS
Pure virtual function is a function with no definition.
They start with keyword virtual and ends with = 0
Syntax for pure virtual function

Virtual void func() = 0;
EXAMPLE OF ABSTRACT CLASS
EXAMPLE
// abstract class CPolygon
class Polygon
{
protected:
int width, height;
public:
void set_values (int a, int b)
{
width=a; height=b;
}
virtual int area () =0;
};
// abstract base class
#include <iostream.h>
class Polygon
{
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
};
class Rectangle: public Polygon
{
public:
int area (void)
{ return (width * height); }
};
class Triangle: public Polygon
{
public:
int area (void)
{ return (width * height / 2); }
};
int main ()
{
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
return 0;
}

You might also like