Ch 6 Polymorphism Timothy Budd Ch 6 Polymorphism
Ch 6. Polymorphism Timothy Budd Ch 6. Polymorphism
Introduction w A static type is associated with a declaration. w A dynamic type is associated with a value. Ch 6. Polymorphism 2
w C++ does not include the concept of interface. Animal Mammal Bird Cat Ch 6. Polymorphism Dog 3
Figure 6. 1 Animal Kingdom in Java abstract class Animal { abstract public void speak(); } class Bird extends Animal { public void speak() { System. out. println("twitter"); } } class Mammal extends Animal { public void speak() { System. out. println("can't speak"); } public void bark() { System. out. println("can't bark"); } } class Cat extends Mammal { public void speak() { System. out. println("meow"); } public void purr() { System. out. println("purrrrr"); } } class Dog extends Mammal { public void speak() { System. out. println("wouf"); } public void bark() { System. out. println("wouf"); } } Ch 6. Polymorphism 4
Figure 6. 2 Animal Kingdom in C++ class Animal { public: virtual void speak() = 0; }; class Bird : public Animal { public: virtual void speak() { printf("twitter"); } }; class Mammal : public Animal { public: virtual void speak() { printf("can't speak"); } void bark() { printf("can't bark"); } }; class Cat : public Mammal { public: void speak() { printf("meow"); } virtual void purr() { printf("purrrrr"); } }; class Dog : public Mammal { public: virtual void speak() { printf("wouf"); } void bark() { printf("wouf"); } }; Ch 6. Polymorphism 5
Virtual & Non-virtual Overriding w Overriding: a method in a parent class is replaced in a child class by a method having exact same type signature. w In C++, overriding uses the keyword virtual. w The variable this is a pointer in C++, a variable in Java. Ch 6. Polymorphism 6
Example of overriding Dog * d = new Dog(); Mammal * m = d; d->bark(); // wouf m->bark(); // can't bark d->speak(); // wouf m->speak(); Animal * a = d; a->speak(); // also wouf // and more wouf d->bark(); // wouf a->bark(); // compile error, not allowed Mammal mm; mm = *d; mm. speak(); d->speak(); // can't speak // although dog will wouf Ch 6. Polymorphism 7
Impact of Virtual on Size w When a class contains a virtual method, an internal table called the virtual method table is created. w This table is used in the implementation of the dynamic binding of message to method required by the virtual method. w Each instance of a class must contain an additional hidden pointer value, which references the virtual method table. Ch 6. Polymorphism 8
Obtaining Type Information from a Dynamic Value w get. Class ( ) in Java Animal a = new Dog(); // following will print class Dog System. out. println("class is " + a. get. Class(). get. Name()); w typeid ( ) in C++ Animal * a = new Dog(); // will print the class Dog println("class is %sn", typeid(*a). name()); Ch 6. Polymorphism 9
Abstract Classes w A pure virtual method must be overridden in subclasses. w An interface can be simulated by pure virtual methods. Ch 6. Polymorphism 10
Abstract Classes w In C++, no equivalent feature for keyword final in Java: protected can have similar effect. Ch 6. Polymorphism 11
Example of Abstract Classes class Key. Press. Handler { // specification for key press event handler public: virtual void key. Down (char c) = 0; }; class Mouse. Down. Handler { // specification for mouse down event handler public: virtual void mouse. Down (int x, int y) = 0; virtual void mouse. Up (int x, int y) = 0; }; class Event. Handler : public Key. Press. Handler, public Mouse. Down. Handler { public: void key. Down (char c) {. . . } void mouse. Down (int x, int y) {. . . } void mouse. Up (int x, int y)( {. . . } }; Ch 6. Polymorphism 12
Downcasting (Reverse Polymorphism) w Downcasting reverses the assignment to a polymorphic variable. w No direct equivalent to the instanceof operation in Java. Ch 6. Polymorphism 13
Downcasting (Reverse Polymorphism) w C++ does not perform a run-time check to ensure the validity of cast conversion. w To resolve the problem, dynamic cast, a part of run-time type information system (RTTI). Ch 6. Polymorphism 14
Example of Downcasting Cat * c = dynamic_cast <Cat *> (a); if (c) printf("variable was a cat"); else printf("variable was not a cat"); void * v =. . . ; // we know, from elsewhere, that v is really a cat Cat * c = static_cast<Cat *>(v); w Whenever possible, use the RTTI instead of standard unchecked cast conversions. Ch 6. Polymorphism 15
Simulating the Dynamic Cast class Mammal { public: virtual bool isa. Dog() { return false; } virtual bool isa. Cat() { return false; } }; class Dog : public Mammal { public: virtual bool isa. Dog() { return true; } }; class Cat : public Mammal { public: virtual bool isa. Cat() { return true; } }; Mammal * fido; Ch 6. Polymorphism 16
Simulating the Dynamic Cast class Dog; class Cat; // forward reference class Mammal { public: virtual Dog * isa. Dog() { return 0; } virtual Cat * isa. Cat() { return 0; } }; class Dog : public Mammal { public: virtual Dog * isa. Dog() { return this; } }; class Cat : public Mammal { public: virtual Cat * isa. Cat() { return this; } }; Mammal * fido; Dog * lassie; Ch 6. Polymorphism 17
Name Resolution w Name resolution is matching a function body to a function name. class Parent { public: void test (int i) { printf("parent test"); } }; class Child : public Parent { public: void test (int i, int i) { printf("child two arg test"); } void test (Parent & p) { printf("child object test"); } }; Ch 6. Polymorphism 18
Name Resolution Child * c = new Child(); c->test(3); // will generate compiler error w Redefine any inherited names that are overloaded with different type signatures. class Child : public Parent { public: void test (int i) { Parent: : test(i); } // redefine inherited method void test (int i, int i) { printf("child two arg test"); } void test (Parent & p) { printf("child object test"); } }; Ch 6. Polymorphism 19
A Forest, Not a Tree w Classes in C++ are not part of a single hierarchy. w If a class is not defined as inheriting from another class, it is the root of its own hierarchy and provides only the behavior defined by the class description. w A typical C++ program contains a number of different class hierarchies, each independent of the others. Ch 6. Polymorphism 20
Virtual Destructors w A destructor is a method that is invoked immediately before a variable it to be deleted. w Declare a virtual destructor if a class has any virtual methods. Ch 6. Polymorphism 21
Example of Destructors class Animal { virtual ~Animal () { printf("goodbye animal"); . . . }; . . . } class Cat : public Mammal { ~Cat () { printf("goodbye cat"); }. . . }; Ch 6. Polymorphism 22
Private Inheritance w If inheritance is protected, fields declared as public in the parent class become protected in the child class. w If inheritance is private, fields declared either as public or protected in the parent become private in the child class. Ch 6. Polymorphism 23
Private Inheritance Parent public Child Private inheritance Public inheritance Ch 6. Polymorphism 24
Example of Private Inheritance class Stack : public List { // assume elements are integers public: push (int val) { add. To. Front(val); } pop () { remove. First. Element(); } top () { return first. Element(); } class Stack : private List { public: push (int val) { add. To. Front(val); } pop () { remove. First. Element(); } top () { return first. Element(); } using is. Empty(); using int size(); }; Ch 6. Polymorphism 25
Inheritance and Arrays w Java permits array to be assigned to a variable that is declared as an array of the parent class Dog [ ] dogs = new Dog[10]; // an array of dog values Animal [ ] pets = dogs; // legal pets[2] = a. Cat; // is this legal? w To prevent, Java actually performs a run-time check on assignments to arrays of objects. Ch 6. Polymorphism 26
Overloading w Overloaded when two or more function bodies are associated with a single function name. class Child : public Parent { public: void test (int i) { Parent: : test(i); } // redefine inherited method void test (int i, int j) { printf("child two arg test"); } void test (Parent & p) { printf("child object test"); } }; Ch 6. Polymorphism 27
Overloading w Functions are distinguished by the compiler by the number and type of arguments used in the function invocation. Dog * operator + (Dog * left, Dog * right) { // return a new Dog value that is the sum of the parents return new Dog(); } Cat * operator + (Cat * left, Cat * right) { return new Cat(); } w Almost all C++ operators can be overloaded. Ch 6. Polymorphism 28
- Slides: 28