Presentation is loading. Please wait.

Presentation is loading. Please wait.

Inheritance: Part I.

Similar presentations


Presentation on theme: "Inheritance: Part I."— Presentation transcript:

1 Inheritance: Part I

2 The classes A class is the description of a family of objects having the same structure and behaviors. Instantiation: instances or objects of the physical representations of a class

3 Structuring ‘classes’
class wheel { } class car { wheel w; // a car has a wheel class vehicle { car c; // ??? class X { } class Y { X x; a car has a wheel a car (does not have an vehicle), but is an vehicle! Y has a X as a component, but a y of Y is NOT a x of X

4 Relationship Between Classes
Composition (class in class) “has-a” relationship Object contains one or more objects of other classes as members Example: A car has a wheel Inheritance (derived class) “is-a” relationship Derived class object can be treated as base class object Example: A car is a vehicle

5 Example 1

6 Example 2

7 Derived Class Employee Manager a ‘Manager’ is a ‘Employee’!
string firstName; string familyName; } class Manager : public Employee { list<Employee*> group; Manager Employee a ‘Manager’ is a ‘Employee’! a derived class object can be treated as a base class object.

8 Class hierarchy Employee Manager Director class Employee {
string firstName; string familyName; } class Manager : public Employee { list<Employee*> group; class Director : public Manager { Employee Manager Director

9 (Public) Inheritance Base class (super-class), derived class (sub-class) Derived class object is a specialization and is a ‘superset’ of the data of its base class object Derived class inherits all members of base class (and members of all its ancestor classes) Public members of the base class Inherited, so accessible Private members of the base class Not accessible directly: comes as a surprise, but ‘privacy’ would have been rendered meaningless if allowed by deriving a new class Accessed through public member functions Friend functions are not inherited

10 Respecting privacy … Yes. No, because of privacy! class Employee {
public: string fullName(); private: string firstName; string familyName; } class Manager : public Employee { void print() const; list<Employee*> group; void Manager::print() const { cout << fullName() << endl; Void Manager::print() const { cout << firstName << familyName << endl; Yes. No, because of privacy!

11 Class-in-Class vs. Inheritance
A class declares another class as its data member, hence creating an object within another object Inheritance and class-in-class are two quite different things and concepts in implementation and OOP. Inheritance has a "is-a" relationship between derived class and base class, while class-in-class is a "has-a" relationship Generally, we can decide whether to use inheritance or class-in-class by common sense. If we can find some common relationship between two or more things, we should use inheritance. For example, Citizen and Student with Citizen as the base class. It makes no sense to implement a Citizen class inside a Student class. In class-in-class, the inner class is a standalone object. Thus, the inner class and the outer class do not share the powerful features in inheritance (such as polymorphism and dynamic binding).

12 Constructors of Derived Classes
class Y : public X { public Y::Y(); }; Y::Y() : X() {

13 If no constructor, use the default base constructor.
class Employee { Employee(); string firstName; string familyName; } class Manager : public Employee { private: list<Employee*> group; int level; Employee e; Manager m; // use default ‘employee’ constructor If no constructor, use the default base constructor.

14 class Employee { public: Employee(); private: string firstName; string familyName; } class Manager : public Employee { Manager(); list<Employee*> group; int level; Manager::Manager() : Employee() { level = … group = … Employee e; Manager m; // use ‘manager’s constructor

15 Passing ‘Arguments’ between ‘Base’ and ‘Derived’ Class Constructors
class Employee { public: Employee(const string& first, const string& family); private: string firstName; string familyName; } class Manager : public Employee { list<Employee*> group; int level; Employee::Employee(const string& first, const string& family) { Manager::Manager(const string& first, const string& family, int l) : Employee(first,family) , level(l) { If a base class has a constructor with arguments, then it is compulsary for the derived class to have a constructor and pass the arguments to the base class constructor.

16 Order of Construction Class objects are constructed from the bottom up: First the base, Then the members, And then the derivated class itself. Members and bases are constructed in order of declaration. When a program creates a derived-class object: The derived-class constructor immediately calls the base-class constructor The base-class constructor’s body (i.e., within {}) executes Then the derived class’s member initializer list execute Finally the derived-class constructor’s body executes This process cascades up the hierarchy if the hierarchy contains more than two levels in a recursive manner

17 Destructor class Y : public X { public Y::~Y(); }; Y::~Y() {

18 Order of Destruction Class objects are destroyed in the opposite order of the construction: First the derived class itself, Then the members, And then the base. Members and bases are destroyed in the reverse order of declaration.

19 Over-riding (not over-loading): Reusing Operations of Base Classes
Derived class may extend or replace base class function of the same name (homonym, homonymous) Therefore, it hides (or overrides) the base-class version of the function Still possible to call the base class function with scope resolution operator class X { public: f(); }; Class Y : public X {}; void Y::f() { X::f(); }

20 class X { public: void print(){cout << "base\n";} }; class Y : public X { void print( int i ){ cout << i << " Derived\n";} void print( char ch ){ cout << ch << " Derived\n";} int main(){ Y y; y.print( 2 ); // print 2 Derived y.print(‘y'); // print y Derived // y.print(); Not O.K.: no matching function for Y::print() }

21 Remarks Beware of ‘infinite recursion’ in function over-riding, if the scope :: operator is not prefixed with the name of the base class when referencing the base class’s member function causes infinite recursion which version of the function to call or function resolution is a major issue!  static or dynamic binding!!!

22 ‘protected’ members The private data members in the base class cannot be accessed by its derived classes The protected data members in the base class can be accessed by its derived classes, but not other non-derived classes The ‘protected’ is the ‘shared privacy’ between base and derived classes !

23 class Employee { protected: string firstName; string familyName; } class Manager : public Employee { public: void print() const; private: list<Employee*> group; void Manager::print() const { cout << firstName << familyName << endl;

24 Protection control: public, protected, private
Intermediate level of protection between public and private For both data members and function members Want the derived class to directly access members while forbid other classes to access them directly protected members in the Base class are accessible to Base class members Base class friends Derived class members Derived class friends

25 Pros/Cons of ‘Protected’
Advantages Derived class can modify values directly Avoid set/get method call overhead  Slight increase in performance Disadvantages No validity checking: Derived class can assign illegal value to protected members Implementation-dependent on the base class Derived class functions are usually very likely dependent on base class implementation Using protected access, base class implementation changes may result in derived class modifications, e.g., a change to a different printing format in the base class may cause the printing function to be changed in the derived class This leads to fragile (brittle) software

26 Example CommissionEmployee BasePlusCommissionEmployee
First name, last name, SSN (Social Security Number, i.e., ID), commission rate, gross sale amount BasePlusCommissionEmployee CommissionEmployee: First name, last name, SSN, commission rate, gross sale amount And also base salary Class BasePlusCommissionEmployee Much of the code is similar to CommissionEmployee Additions private data member baseSalary Methods setBaseSalary and getBaseSalary

27 Derived from class CommissionEmployee
Is a CommissionEmployee Inherits all public members Use base-class initializer syntax to initialize base-class data member Has data member baseSalary Base class implementation CommissionEmployee1.h, CommissionEmployee1.cpp Derived class implementation BasePlueCommissionEmployee1.h, BasePlusCommissionEmployee1.cpp Compilation error because derived class cannot directly access private members of CommissionEmployee class in print() and earnings()

28 tester2.cpp Sample Output
Employee information obtained by get functions: First name is Bob Last name is Lewis Social security number is Gross sales is Commission rate is 0.04 Base salary is Updated employee information output by print function: base-salaried commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 base salary: Employee's earnings: $

29 order.cpp Sample Output (1/2)
CommissionEmployee constructor: commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 CommissionEmployee destructor: base-salaried commission employee: Lisa Jones social security number: gross sales: commission rate: 0.06 CommissionEmployee constructor called for object in block; destructor called immediately as execution leaves scope Base-class CommissionEmployee constructor executes first when instantiating derived-class BasePlusCommissionEmployee object BasePlusCommissionEmployee constructor: base-salaried commission employee: Lisa Jones social security number: gross sales: commission rate: 0.06 base salary: CommissionEmployee constructor: commission employee: Mark Sands social security number: gross sales: commission rate: 0.15 Derived-class BasePlusCommissionEmployee constructor body executes after base-class CommissionEmployee’s constructor finishes execution Base-class CommissionEmployee constructor executes first when instantiating derived-class BasePlusCommissionEmployee object

30 order.cpp Sample Output (2/2)
BasePlusCommissionEmployee constructor: base-salaried commission employee: Mark Sands social security number: gross sales: commission rate: 0.15 base salary: BasePlusCommissionEmployee destructor: CommissionEmployee destructor: commission employee: Mark Sands Derived-class BasePlusCommissionEmployee constructor body executes after base-class CommissionEmployee’s constructor finishes execution Destructors for BasePlusCommissionEmployee object called in reverse order of constructors BasePlusCommissionEmployee destructor: base-salaried commission employee: Lisa Jones social security number: gross sales: commission rate: 0.06 base salary: CommissionEmployee destructor: commission employee: Lisa Jones Destructors for BasePlusCommissionEmployee object called in reverse order of constructors

31 Summary ‘is-a’ relationship Public inheritance ‘protected’
Different from ‘has-a’ or ‘uses-a’, or … by class-in-class Public inheritance Public Private ‘protected’ Constructors/destructors Redefinition (over-riding)  which version for which object ? Not inherited: Friend functions

32 Inheritance: Part II

33 A More General Derived Class
class Y : public X {…} class Y : protected X {…}; class Y : private X {…};

34 Increasing Access Restrictions
public inheritance (written as class derived: public base) Base class public members  derived class public members Base class protected members  derived class protected members All classes can directly access the public members Only the derived classes can directly access the protected members protected inheritance (written as class derived: protected base) Base class public and protected members  derived class protected members Classes in the inheritance hierarchy can still access the members (because they are protected members), but not for other classes private inheritance (written as class derived: private base) Base class public and protected members  derived class private members Classes in the downstream inheritance hierarchy can no longer access the members (and neither can all the other classes) public protected private Base class Derived class

35 Types of Inheritance and Member Access

36 public_derived pub_d; protected_derived prot_d;
class Base { public: void f() {cout << "Base::f()" << endl;} protected: void g() {cout << "Base::g()" << endl;} }; class public_derived: public Base { class protected_derived: protected Base { class private_derived: private Base { int main(){ Base b; public_derived pub_d; protected_derived prot_d; private_derived priv_d; b.f(); // b.g(); error: 'void Base::g()' is protected pub_d.f(); // pub_d.g(); error: 'void Base::g()' is protected // prot_d.f(); error: 'void Base::f()' is inaccessible // prot_d.g(); error: 'Base' is not an accessible base of 'protected_derived' // priv_d.f(); similar error as above // priv_d.g(); similar error as above return 1; }

37 Class hierarchy Direct base class Indirect base class
Inherited explicitly (one level up hierarchy) E.g., driver licenses and license Indirect base class Inherited two or more levels up hierarchy E.g., car license and license Single inheritance Inherits from one base class E.g., the above license example Multiple inheritance Inherits from multiple base classes Base classes possibly unrelated E.g., A “university student” is both a “hard-working person” and a “clever person”

38 A B C D E F The inheritance graph for simple inheritance is a tree. The transitive closure of the inheritance relationship of the tree is a relation of total order.

39 p A B C D p A B C D A B C D p p p No conflict for A of p Conflict between B and C for A of p Not a tree, only a partial ordering, some objects are not comparable!

40 B C p p A Conflict between B and C for A of p, So to redefine p in A

41 Multiple Inheritance When a derived class inherits members from two or more base classes Provide comma-separated list of base classes after the colon following the derived class name Can cause ambiguity problems Should be used only by experienced programmers Newer languages do not allow multiple inheritance A common issue occurs if more than one base class contains a member with the same name Solved by using the scope resolution operator (by the user!)

42 Multiple Inheritence (Cont.)
Should be used when an “is a” relationship exists between a new type and two or more existing types i.e. type A “is a” type B and type A “is a” type C Can introduce complexity into a system Great care is required in the design of a system to use multiple inheritance properly Should not be used when single inheritance and/or composition will do the job

43 Example: Base1.h, Base2.h, Derived.h, Derived.cpp, multiple.cpp

44 Class Base1 declares member function getData
Base1.h class Base1 { public: Base1( int parameterValue ) value = parameterValue; } int getData() const return value; protected: int value; }; Class Base1 declares member function getData

45 Class Base2 also declares member function getData, same name as Base1
Base2.h class Base2 { public: Base2( char characterData ) letter = characterData; } char getData() const return letter; protected: char letter; }; Class Base2 also declares member function getData, same name as Base1

46 Derived.h #include "Base1.h" #include "Base2.h" class Derived : public Base1, public Base2 { friend ostream& operator<<( ostream&, const Derived&); public: Derived(int, char, double); double getReal() const; private: double real; }; Class Derived inherits from both class Base1 and class Base2 through multiple inheritance

47 Base1 base1(10); Base1* base1Ptr = 0; Base2 base2('Z'); Base2* base2Ptr = 0; Derived derived( 7, 'A', 3.5 ); // print data members of base-class objects cout << "Object base1 contains integer " << base1.getData() << "\nObject base2 contains character " << base2.getData() << "\nObject derived contains:\n" << derived << "\n\n"; // print data members of derived-class object // scope resolution operator resolves getData ambiguity cout << "Data members of Derived can be accessed individually:" << "\n Integer: " << derived.Base1::getData() << "\n Character: " << derived.Base2::getData() << "\nReal number: " << derived.getReal() << "\n\n"; cout << "Derived can be treated as an object of either base class:\n"; // treat Derived as a Base1 object base1Ptr = &derived; cout << "base1Ptr->getData() yields " << base1Ptr->getData() << '\n'; // treat Derived as a Base2 object base2Ptr = &derived; cout << "base2Ptr->getData() yields " << base2Ptr->getData() << endl;

48 multiple.cpp Sample Output
Note the use of base-class pointer pointing to a derived-class objects Invoking the member function of the derived object Object base1 contains integer 10 Object base2 contains character Z Object derived contains: Integer: 7 Character: A Real number: 3.5 Data members of Derived can be accessed individually: Derived can be treated as an object of either base class: base1Ptr->getData() yields 7 base2Ptr->getData() yields A

49 Software Engineering: Software Customization with Inheritance
Inheriting from existing classes Can include additional members Can redefine base-class members No direct access to base class’s source code Only links to object code Good for those independent software vendors (ISVs) Develop proprietary code for sale/license Available in object-code format Users derive new classes Without accessing ISV proprietary source code


Download ppt "Inheritance: Part I."

Similar presentations


Ads by Google