320 likes | 568 Views
Inheritance. Reference: Chapter 7. Inheritance Terminology. inheritance hierarchy “is a” relationship base class (superclass) derived class (subclass) class member access specifiers public protected private abstract class member function overriding member slicing
E N D
Inheritance Reference: Chapter 7
Inheritance Terminology • inheritance hierarchy • “is a” relationship • base class (superclass) • derived class (subclass) • class member access specifiers • public • protected • private • abstract class • member function overriding • member slicing • multiple inheritance
Class Access Specifiers • Public • Member functions • Friend functions • Non-friend functions • Protected • Member functions • Friend functions • Private • Member functions • Friend functions
Class Access Specifiers (continued) • Why Use Protected? • Allows derived classes to use member functions and data • items directly (don’t need to use base class accessor methods) • Still hides these member functions and data items from • non-friend functions • Watch Out! • Using “Protected” violates encapsulation! • If the protected members are changed in the base class, • it may affect the derived class code • New derived classes will have access to the protected • members • Use only in “emergency” situations
Types of Inheritance • Public • The most common type • Protected • Rare • Private • Rare
Public Inheritance • Specified by: • class name: public base-class-name • Inheritance: • public in base class, public in derived class • protected in base class, protected in derived class • private in base class, not accessible in derived class • (must use public or protected base class accessor methods) • By far, the most common type of inheritance.
Protected Inheritance • Specified by: • class name: protected base-class-name • Inheritance: • public in base class, protected in derived class • protected in base class, protected in derived class • private in base class, not accessible in derived class • (must use public or protected base class accessor methods) • Rarely used.
Private Inheritance • Specified by: • class name: private base-class-name • Inheritance: • public in base class, private in derived class • protected in base class, private in derived class • private in base class, not accessible in derived class • (must use public or protected base class accessor methods) • Rarely used.
Public Inheritance Example class Time { public: Time(int h = 0, int m = 0, int s = 0); // cannot be inherited void set(int h, int m, int s); // overriden to set zone void increment(); // inherited void write() const; // overriden to print zone private: int hrs, mins, secs; }; // all data members inherited class ExtTime: public Time { public: ExtTime(int h = 0, int m = 0, int s = 0, ZoneType z = EST); void set(int h, int m, int s, ZoneType z); void write() const; private: ZoneType zone; }; // new data member
Public Inheritance Example Using Protected class Time { public: Time(int h = 0, int m = 0, int s = 0); // cannot be inherited void set(int h, int m, int s); // overriden to set zone void increment(); // inherited void write() const; // overriden to print zone protected: // ENCAPSULATION VIOLATION! int hrs, mins, secs; }; // all data members inherited class ExtTime: public Time { public: ExtTime(int h = 0, int m = 0, int s = 0, ZoneType z = EST); void set(int h, int m, int s, ZoneType z); void write() const; private: ZoneType zone; }; // new data member
Time Class Code #include <iostream.h> #include "time.H" Time::Time(int initHrs, int initMins, int initSecs) : hrs(initHrs), mins(initMins), secs(initSecs) { } void Time::Set(int hours, int minutes, int seconds) { hrs = hours; mins = minutes; secs = seconds; }
Time Class Code (continued) void Time::Increment() { secs++; if (secs > 59) { secs = 0; mins++; if (mins > 59) { mins = 0; hrs++; if (hrs > 23) hrs = 0; } } }
Time Class Code (continued) void Time::Write() const { if (hrs < 10) cout << '0'; cout << hrs << ':'; if (mins < 10) cout << '0'; cout << mins << ':'; if (secs < 10) cout << '0'; cout << secs; }
Extended Time Class Code (Public Inheritance) #include <iostream.h> #include "exttime.H" ExtTime::ExtTime(int initHrs, int initMins, int initSecs, ZoneType initZone) : Time(initHrs, initMins, initSecs) { zone = initZone; } void ExtTime::Set(int hours, int minutes, int seconds, ZoneType timeZone) { Time::Set(hours, minutes, seconds); zone = timeZone; }
Extended Time Class Code (continued) void ExtTime::Write() const { static char zoneString[8][4] = { "EST", "CST", "MST", "PST", "EDT", "CDT", "MDT", "PDT" }; Time::Write(); cout << ' ' << zoneString[zone]; }
Operations on Base and Derived Class Objects • Time t(10, 5, 0); • ExtTime et(20, 15, 10, EST); • A derived class object can be assigned to a base class • object • t = et; // legal • Member slicing occurs. • A base class object cannot be assigned to a derived class • object • et = t; // illegal! Not all data members can be filled
Operations on Base and Derived Class Objects (continued) • Time t(10, 5, 0); • ExtTime et(20, 15, 10, EST); • A base class pointer can point to a base class object • Time tPtr = &t; • A dervied class pointer can point to a derived class object • ExtTime etPtr = &et; • A base class pointer can point to a derived class object • Time tPtr = &et; // legal, but can only access base class data • members • A derived class pointer cannot point to a base class object • ExtTime etPtr = &t; // illegal!
Sample Program Using Time and Extended Time Code: #include <iostream.h> #include "exttime.H" void main() { Time t1, t2(15, 10, 5); cout << "Instantiation of t1 = "; t1.Write(); cout << endl; cout << "Instantiation of t2 = "; t2.Write(); cout << endl; Output: Instantiation of t1 = 00:00:00 Instantiation of t2 = 15:10:05
Sample Program Using Time and Extended Time Code: ExtTime et1, et2(30, 25, 20, CST); cout << "Instantiation of et1 = "; et1.Write(); cout << endl; cout << "Instantiation of et2 = "; et2.Write(); cout << endl; Output: Instantiation of et1 = 00:00:00 EST Instantiation of et2 = 30:25:20 CST
Sample Program Using Time and Extended Time Code: et1.Set(50, 45, 40, MDT); cout << "et1 after Set(50, 45, 40, MDT) = "; et1.Write(); cout << endl; Output: et1 after Set(50, 45, 40, MDT) = 50:45:40 MDT
Sample Program Using Time and Extended Time Code: // Set and display an extended time using base class Set // Should invoke base class Set, but get a compiler error // that the 4th parameter (zone) is missing. Should be an // overload, but compiler sees it as an override. // // et1.Set(70, 65, 60); // cout << "et1 after base class Set = "; // et1.Write(); cout << endl;
Sample Program Using Time and Extended Time Code: // Mixing base and derived class objects t1 = et1; // Base class = derived class is legal cout << "t1 after t1=et1: "; t1.Write(); cout << endl; // et2 = t1; // Derived class = base class illegal -- syntax error! Output: t1 after t1=et1: 50:45:40
Sample Program Using Time and Extended Time Code: // Mixing base and derived class pointers Time *tPtr; ExtTime *etPtr; // Base class pointer pointing to base class object tPtr = &t1; // 50, 45, 40 cout << "tPtr=&t1, tPtr->Write() = "; tPtr->Write(); cout << endl; // Dervied class pointer pointing to derived class object etPtr = &et2; // 30, 25, 20, CST cout << "etPtr=&et2, etptr->Write() = "; etPtr->Write(); cout << endl; Output: tPtr=&t1, tPtr->Write() = 50:45:40 etPtr=&et2, etptr->Write() = 30:25:20 CST
Sample Program Using Time and Extended Time Code: // Base class pointer pointing to derived class object tPtr = &et2; // 30, 25, 20, CST cout << "tPtr=&et2, tPtr->Write() = "; tPtr->Write(); cout << endl; // Try to access a derived class method // tPtr->WriteZone(); // illegal -- syntax error! // Derived class pointer pointing to base class object // etPtr = &t1; // illegal -- syntax error! Output: tPtr=&et2, tPtr->Write() = 30:25:20
Constructors and Destructors in Derived Classes • Base class constructors are not inherited by derived classes • A derived class’ constructor must invoke its base class’ • constructor (or use its base class’ default constructor) • ExtTime::ExtTime(int initHrs, int initMins, int initSecs, • ZoneType initZone) : • Time(initHrs, initMins, initSecs) • { • zone = initZone; • } • The base class’ constructor is called before the derived • class’ constructor code is executed
Constructors and Destructors in Derived Classes (continued) • Destruction takes place in the opposite order of construction • Therefore, the derived class’ destructor is invoked before • the base class’ destructor
Constructor/Destructor Example class Point { // From “C++: How to Program, by Dietel & Dietel public: Point(int = 0, int = 0); ~Point(); protected: int x, y; {; class Circle: public Point { public: Circle(double r = 0.0, int x = 0, int y = 0); ~Circle(); private: double radius; };
Constructor/Destructor Example (continued) Point::Point(int a, int b) { x = a; y = b; cout << “Point constructor: “ << ‘[‘ << x << “, “ << y << ‘]’ << endl; } Point::~Point() { cout << “Point destructor: “ << ‘[‘ << x << “, “ << y << ‘]’ << endl; }
Constructor/Destructor Example (continued) Circle::Circle(double r, int a, int b) : Point(a, b) { radius = r; cout << “Circle constructor: radius is “ << radius << “ [“ << x << “, “ << y << ‘]’ << endl; } Circle::~Circle() { cout << “Circle destructor: radius is “ << radius << “ [“ << x << “, “ << y << ‘]’ << endl; }
Constructor/Destructor Example (continued) #include <iostream.h> #include “point.h” #include “circle.h” void main() { { Point p(11, 22); } cout << endl; Circle circle1(4.5, 72, 29); cout << endl; Circle circle2(10.0, 5, 5); cout << endl; }
Constructor/Destructor Example (continued) Point constructor: [11, 22] Point destructor: [11, 22] Point constructor: [72, 29] Circle constructor: radius is 4.5 [72, 29] Point constructor: [5, 5] Circle constructor: radius is 10.0 [5, 5] Circle destructor: radius is 10.0 [5, 5] Point destructor: [5, 5] Circle destructor: radius is 4.5 [72, 29] Point destructor: [72, 29]