McGill University Computer Science Department COMP 322 : Introduction to C++ Winter 2009 Lecture 5: Inheritance Sami Zhioua March 11 th, 2009 1
Inheritance Inheritance is a form of software reusability in which programmers create classes that absorb an existing class s data and behaviours and enhance them with new capabilities. Inheritance encourages the reuse of proven and debugged high-quality software, which increases the likelihood that a system will be implemented effectively. When creating a class, the programmer can designate that the new class should inherit the members of an existing class. A derived class represents a more specialized group of objects. Base Class A derived class contains behaviours inherited from its base class plus additional behaviours. It also can customize behaviours inherited from the base class. Derived Class C++ offers single inheritance and multiple inheritance and also public, private and protected inheritance. 2
Example Private members of the base class are inherited by the derived class. But, they cannot be accessed directly from the derived class. Person Student 3
Protected Members Protected access offers an intermediate level of protection between public and private. A protected member in the base class can be accessed by members and friends of that base class and by members and friends of any class derived from that base class. x can be accessed from anywhere. y can be accessed from Base, the friends of Base, Base s derived classes and their friends. z can be accessed from the Base and the friends of Base. 4
Public Vs nonpublic inheritance Base Class Base Class Derived Class Public inheritance : public member protected member private member public member protected member private member Derived Class Protected inheritance : public member protected member private member protected member protected member private member Private inheritance : public member protected member private member private member private member private member Default : private inheritance 5
Accessing members of the base class Derived class member functions can refer to base class (public and protected) members as follows : - If the member is not redefined in the derived class : use simply the name - If the member is redefined in the derived class : use the base class name followed by the scope resolution operator (::). 6
What is inherited from the base class? A derived class inherits every member of a base class except : - its constructor and its destructor - its operator=() members - its friends When a new object of a derived class is created the default constructor of the base class (i.e., the constructor with no parameters) is called by default. If you want that another base class constructor be called, you can specify it in each constructor definition of the derived class (See Student example in previous slide). When an object of a derived class is destroyed the destructor of the base class is always called. 7
Polymorphism Shape int getarea() Rectangle int getarea() Triangle int getarea() Circle int getarea() Triangle Rectangle Circle Circle Triangle Illegal : the elements of the array have different types Shape Shape Shape Shape Shape Legal : but not what we want Shape * Shape * Shape * Shape * Shape * Legal : needs polymorphism 8
Polymorphism In C++, a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature, that brings Object Oriented Methodologies to its full potential Shape * Shape * Shape * Shape * Shape * 9
Static Dispatch Vs Dynamic dispatch 10
Static Dispatch Vs Dynamic dispatch The compile-time type of (*p) is Person. The runtime type of (*p) is Student. In C++, by default, the decision on which member function to invoke (base or derived) is made on the basis of the compile-time type. This is called static dispatch When it is the runtime type which is used to invoke methods : This is called dynamic dispatch Dynamic dispatch is almost always the preferred dispatch method!! Why the static dispatch is the default in C++???!!! efficiency 11
Keyword Virtual To achieve dynamic dispatch in C++, the base class method must be marked with the keyword Virtual : - A virtual function uses dynamic dispatch. - A nonvirtual function uses static dispatch. Once a function is marked virtual, it is virtual from that point down in the inheritance hierarchy. If a method is overridden in a derived class, it should be declared virtual in the base class. Only if a member function is intended to be invariant in an inheritance hierarchy does it make sense to not mark it as virtual. 12
Slicing p only has room for name and ssn data members. gpa cannot be copied into p because it has no room for it. If a derived class object is copied into a base class object, only the base class portion is actually copied. The derived class object has been sliced. Slicing occurs also when objects are passed using call-by-value. Will print only the base class portion! Important : Call-by-value should never be used in conjunction with inheritance. 13
Abstract Methods and Classes Abstract methods (sometimes called pure virtual methods) are methods that serve as placeholders, with implementations deferred to concrete subclasses. In C++, a method is abstract if: - It is declared virtual - The declaration is followed by =0. In C++, a class is abstract if it has at least one abstract method. Abstract classes cannot be instantiated. A C++ class with no abstract methods is not abstract. 14
Example Write a program that : - creates an array of 3 shapes - prints them - prints their total area 15
Multiple inheritance Single inheritance Base_Class_1 Derived_Class_1 Derived_Class_2 Derived_Class_3 16
Multiple inheritance In C++ it is perfectly possible that a class inherits members from more than one class. Base_Class_1 Base_Class_2 Derived_Class_1 Derived_Class_2 Derived_Class_3 If done properly, multiple inheritance can be very useful. But.. If multiple inheritance in which two or more base classes are not purely abstract classes (eq. interfaces in Java) can create significant complications because the implementations that are inherited could be conflicting. 17
Multiple inheritance Base_Base_Class Base_Class_1 Base_Class_2 Derived_Class 18
Multiple inheritance Person Student Employee StudentEmployee 19
Multiple inheritance Which gethours is inherited? Two copies of hours?! One or two copies?! 20
Multiple inheritance 21
Exercices 1. 2. 3. 4. What does the keyword virtual do? What is slicing? Why is it bad to declare a base class parameter using call-by-value? How are heterogeneous collections stored in C++? 5. Define a hierarchy that includes - Person, - Student, - Athlete, - StudentAthlete, - FootballPlayer, - BasketBallPlayer, - StudentFootballPlayer, - StudentBasketballPlayer, and - StudentFootballAndBasketballPlayer. Give a Person a name, a Student a GPA, an Athlete a uniform number, a FootballPlayer a boolean representing true for offense, and false for defense, and BasketballPlayer a scoring average (as a double). Define appropriate data representations, constructors, destructors, and methods, and make use of virtual inheritance. Observe that StudentFootballAndBasketballPlayer will have two uniform numbers. Write a test program that obtains both numbers. 22