object oriented programming polymorphism
TRANSCRIPT
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 higherAnimal
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
POLYMORPHISMclass 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 CatSuch 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 = ▭ 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 = ▭ Polygon * ppoly2 = &trgl; ppoly1->set_values (4,5); ppoly2->set_values (4,5); cout << ppoly1->area() << '\n'; cout << ppoly2->area() << '\n'; return 0;
}