370 likes | 915 Views
Inheritance. Definition Relationships Member Access Control Data Encapsulation Overloading vs. Overriding Constructors & Destructors Multiple Inheritance. Definition. Inheritance
E N D
Inheritance • Definition • Relationships • Member Access Control • Data Encapsulation • Overloading vs. Overriding • Constructors & Destructors • Multiple Inheritance
Definition • Inheritance • A form of software reusability in which new classes are created from existing classes by absorbing their attributes and behaviors, and overriding or embellishing these with capabilities the new classes require • Software reusability saves time in program development by reusing proven and debugged high-quality software
Definition • Single inheritance • A class is derived from one base class • Quite straightforward • Multiple inheritance • A class is derived from multiple (possibly unrelated) base classes • Complex and error prone (ambiguity problems)
Inheritance • What do we get from our parents? • Attributes & behaviors • What is a class composed of? • Data members (attributes) • Member functions (behaviors) • A class can “inherit” the data members & member functions from its parent class • Parent class – general • Child class – specific
Inheritance • Inheritance • Form of software reuse • Built upon the work of others (other classes) • Base class (parent) • The original class • Other classes will be built using this as a starting point
Inheritance • Derived class (child) • A new class construed using information present in the base class • A derived class is more specific than its base class & represents a smaller group of objects • A class can be both a base class and a derived class • C inherits from B (base class) • And B (derived class) inherits from A
Relationships • View inheritance as an “is-a” relationship • The derived class “is-a” specialized/extended object of the base class • Inheritance is not a “has-a” relationship • “has-a” relationships deal with composition • A person “has-a” a brain • An operating system “has-a” ready queue • A room “has-a” door
Relationships • View inheritance as an “is-a” relationship • A person “is-a” mammal • A mammal “is-an” animal • A square “is-a” shape • A lab “is-a” room
Member Access Control • Public Access • Any public member of the base class can be “seen” by a derived class • Private Access • Any private member of the base class cannot be “seen” by a derived class • Problem • Need Public so derived class can see members • Need Private for data encapsulation
Protected Access • Can access Protected data members & member functions of a base class • This section can be seen by a derived class with the “is-a” property • This section cannot be seen by a class with a “has-a” property
Data Encapsulation • Also called “data hiding”, or “information hiding” • The implementation details of a class are hidden within the classes themselves • Classes must interact with one another through well-defined interfaces • Hiding the details, while supplying an interface is an important underlying theme behind classes, or user-defined data types
Problems with Inheritance • The derived class can inherit public member function implementations that it does not need to have • On the other hand, a programmer can override the function with another function which has the appropriate implementation • Also note that friend functions are not inherited
Basic Format class BaseClass{ protected: //data members public: //member functions } class DerivedClass: public BaseClass{ //extra data & functions }
Class Pear class Pear { int a,b; public: Pear(int x=0, int y=0): a(x),b(y){} void setA(int x){a=x;} void setB(int x){b=x;} int getA(){return a;} int getB(){return b;} friend ostream &operator<< (ostream &apple, const Pear &p) {apple<<p.a<<", "<<p.b; return apple;} }; • Stores two integers • Member functions • Constructor • Set both values • Get both values • Friend output • See pear.txt
Class Truffle • Stores three integers • Add new integer data • Add new set & get functions • Modify friend output operator • Want to build off class Pear (inheritance) • Add word “protected” to base class Pear • Add “:public Pear” in Truffle’s class declaration • Add explicit Pear constructor to Truffle constructor (otherwise will be called implicitly) • See truffle.txt
Class Pear & Truffle class Pear { protected: int a,b; public: Pear(int x=0, int y=0): a(x),b(y){} void setA(int x){a=x;} void setB(int x){b=x;} int getA(){return a;} int getB(){return b;} friend ostream &operator<< (ostream &apple,const Pear &p) {apple<<p.a<<”, ”<<p.b; return apple;} }; class Truffle:public Pear{ int c; public: Truffle(int x=0, int y=0, int z=0) :Pear(x,y),c(z){ } void setC(int x){c=x;} int getC(){return c;} friend ostream & operator<< (ostream & banana, const Truffle & t){ Pear p = static_cast<Pear>(t); banana<<p<<", "<<t.c; return banana; } };
Driver Program void main(){ Pear p; p.setA(5); cout<<p<<endl; //5, 0 Truffle t(3); t.setB(9); t.setC(2); cout<<t<<endl; //3, 9, 2 }
Class Exercise • See exercise1.txt
Arrays of Class Objects • An object of a derived class can also be treated as an object of its corresponding base class • Can have an array of base class objects, with each array element being a different derived class objects • Pear *p[3] = {new Pear, new Truffle, new Quad}; • Reverse is not true: a base-class object is not also automatically a derived-class object • Cannot do this: • Quad *q[3] = {new Pear, new Truffle, new Quad};
Casting • Upcasting a pointer • Using an explicit cast to convert a derived-class pointer to a base-class pointer • No problem during run-time (maybe loss of data) • Downcasting a pointer (dangerous) • Using an explicit cast to convert a base-class pointer to a derived-class pointer • Pointer must match the type of the object to which it points • Otherwise get possible run-time errors (garbage data)
Casting Example • See casting.txt
More Casting • Can you cast a banana to an apple, if they are both of class fruit? • Yes, but you need a conversion constructor • See fruit.txt
Accessing Base-class Functions • Use scope resolution operator (::) to access base-class data and functions from the derived-class class Pear{ protected: int a,b; . . . class Truffle:public Pear { int c; . . . bool AbiggerC(){ return Pear::a > c; } }; void main(){ Truffle t(3,9,2); cout<<t.AbiggerC()<<endl; //1 }
Accessing Base-class Functions class Pear { private: int a,b; . . . class Truffle:public Pear { . . . bool AbiggerC(){ //cannot access private data: return Pear::getA() > c; }
Accessing Base-class Functions • Can access public or protected data members & member functions, but cannot access private data members & member functions • See bigger.txt
Overriding vs. Overloading • Overriding – when the derived class and the base class have a function of the same signature • When this function is mentioned by name in the derived class, the derived-class version is automatically selected • Overloading – functions of the same name with different signatures
Overriding vs. Overloading class Pear { //See overriding.txt . . . int sum(){return a + b;} . . . class Quad:public Truffle { . . . int sum(){return a+b+c+d;} int sum(int x){return a+b+c+d+x;} . . . void main(){ Pear p(1,1); Quad q(1,1,1,1); cout<<p.sum()<<" "<<q.sum(); //overriding cout<<q.sum(10)<<endl; //overloading }
Direct & Indirect Base Classes • Direct base class • Is explicitly listed in that derived class’ header with the colon (:) notation when that derived class is declared • Indirect base class • Not explicitly listed in the derive class’s header • Is inherited from two or more levels up the class hierarchy
Constructors & Destructors • Derived class constructor always calls the constructor of its base class first • If no constructor exists for derived class, the default constructor is called • Destructors are reversed - derived class destructor is called before the base class destructor • If no destructor exists for derived class, the default destructor is called
class Truffle:public Pear { int c; public: Truffle():Pear(0,0),c(0) {cout<<"Truffle 1"<<endl;} Truffle(int x):c(x) {cout<<"Truffle 2"<<endl;} Truffle(int x, int y, int z): Pear(x,y),c(z) {cout<<"Truffle 3"<<endl;} ~Truffle() {cout<<"Truffle Destructor"<<endl;} }; • Class Exercise • What’s the output of this program? • See exercise2.txt class Pear { protected: int a,b; public: Pear():a(0), b(0) {cout<<"Pear 1"<<endl;} Pear(int x, int y):a(x),b(y) {cout<<"Pear 2"<<endl;} ~Pear() {cout<<"Pear Destructor"<<endl;} }; void main(){ {Pear a;} {Truffle b;} {Pear c(1,2);} {Truffle d(3);} {Truffle e(4,5,6);} }
Software Engineering • Inheritance can be used to customize existing software • A derived class inherits the attributes & behaviors of a base class, and then additional attributes & behaviors are added • In C++, you only need the base class’ object code and the base class’ header file • A software vender can develop classes for sale • If the user has the object code & header files, then can create new software to suit own needs • The vender’s source code is never revealed
Multiple Inheritance • A class may be derived from more than one base class • For example, type A “is-a” type B and type A “is-a” type C • Can have ambiguity problems • For example, if both class B & C have a function that A inherits (and does not override) • Solution is to use the scope resolution operator to clarify which class the function belongs to (or can use the appropriate pointer to that class)
Example • See mutiple.txt