330 likes | 456 Views
Inheritance. Today: Inheritance and derived classes. Is-A relationship class hierarchies proper inheritance (pure) polymorphism virtual functions protected members inheritance and constructors/destructors. Inheritance and Derived Classes. Problem domain objects are related
E N D
Today: Inheritance and derived classes • Is-A relationship • class hierarchies • proper inheritance • (pure) polymorphism • virtual functions • protected members • inheritance and constructors/destructors
Inheritance and Derived Classes • Problem domain objects are related • Has-A relationship • a Car has: Engine, Transmission, Suspension etc. • usually modeled in C and C++ as composition • classes/structs have other structs as members • Another relationship: Is-A (also known as Kind-Of • specialization/generalization
Example of an Is-A relationship • Employee • name, hiring date, department • Manager • same behavior (services and state) as employee, plus: • employees managed; level
Implementing Is-A in C struct Employee { name, dept, etc } struct Manager { Employee emp; /* containment */ Employee managed[25]; unsigned level; } • Implemented Is-A as Has-A (containment)
Problems with Is-A implementation • Even though a Manager “object” has everything an Employee has plus more… • Cannot pass a Manager variable where Employee is expected • Same for pointers: Manager* and Employee* • What about a mid-level Manager?
Modeling Is-A in C++: Public Inheritance class Manager : public Employee { // data and methods // unique to Manager } • Employee - a base class • Manager - a derived class
Inheriting methods and data class Employee { get/setName(); … } Employee e; Manager m; cout << e.getName(); cout << m.getName();
Inheriting methods and data • All Employee public members and methods are retained (inherited) by Manager • Employee public methods can be used by Manager as if it were an Employee • easy reuse of code • Constructors, destructors, operator= are not inherited
Access rules for derived classes • (Public inheritance only) • public data and functions remain public • private members are not accessible in derived classes. • Why? Trivial to defeat encapsulation by deriving a class
Class hierarchies • Typical to discover new relationships between domain objects/new specialized objects class Director : public Manager { Car corporateVehicle; … }
Manager Class hierarchies Employee Employee Base type Is-A special kind of Employee Director Is-A special kind of Manager
Temporary Manager Class hierarchies Employee Employee Director
Class hierarchies • Typically “root” object at the top - inverted tree
Proper Inheritance • When is a relationship Is-A? class Rectangle { ... } class Square : public Rectangle { ... }
Proper Inheritance class Rectangle { // methods to set height and width } class Square : public Rectangle { // method to set size } • Cannot call setHeight()/setWidth() on a Square
Proper Inheritance • Criterion: substitutability • An object of class Derived can be substituted for an object of class Base everywhere • Not true for Rectangle(Base) and Square (Derived)
Three options • allow Square to have different width and height • do not guarantee that setWidth()/setHeight work on all Rectangle • drop the inheritance relationship
Improper inheritance: another example class Bird { void fly(); … } class Penguin : public Bird { // cannot fly }
Improper inheritance: general case • A base class with an “extra” capability a derived class can't satisfy. • Three options: • make the base class weaker • make the derived class stronger • eliminate the proposed inheritance relationship
Bad way of dealing with improper inheritance • Attempt to determine actual type of object at run-time: if (a shape is actually a Rectangle) process it as a rectangle elseif (a shape is a Square) do not attempt to change W and H separately else ???
Polymorphic class pointers Employee* eptr; Employee e; Manager m; eptr = &e; eptr = &m; • Similar for references
Polymorphic pointers and references • A pointer or reference of a Base class can always refer to an object of a Derived class (because a Derived Is-A Base) • But not vice versa
Virtual functions • Employee::print() • print name, department • Manager::print() • print Employee information + level
Virtual functions class Employee { virtual void print(); … } class Manager { virtual void print(); … }
Virtual functions Employee* eptr; Employee e; Manager m; eptr = &e; eptr->print(); // Employee::print eptr = &m; eptr->print(); // Manager::print
Virtual functions • Actual function called depends on the dynamic type of the pointer • Static vs. dynamic types • Virtual functions use late binding
Alternative: explicit type field class Employee { enum EmplType { E, M }; EmplType type; void print(); … } switch (e->type) { … }
Virtual functions: details • Signatures of virtual functions in base and derived class must exactly match
Prohibiting virtual function resolution Manager::print() { // print Manager-specific stuff // explicitly call print() from // base class Employee::print(); }
Inheritance and constructors • Objects are constructed “bottom-up” • base first • then member objects • finally, derived class • Constructor in derived class must call constructor(s) for base and member classes
Inheritance and destructors • Destructor in Derived automatically calls destructor in Base
Summary • Is-A relationship • Access inheritance • class hierarchies • proper inheritance • Virtual functions • Static vs. dynamic type • Inheritance and constructors/destructors