1 Lecture 6 - 7 OOP Course. 2 6. Inheritance Basics Shape.
-
Upload
ginger-holland -
Category
Documents
-
view
222 -
download
2
Transcript of 1 Lecture 6 - 7 OOP Course. 2 6. Inheritance Basics Shape.
3
MotivationMotivation• Suppose we want to computerize our personnel
records• We start by identify the two main types of
employees we have:
class Engineer { char* name; short year_born; short department; int salary; char* degrees;public: void give_raise(
int how_much);// ... };
class SalesPerson { char* name; short year_born; short department; int salary; double *comission_rate;public: void give_raise(
int how_much);// ... };
4
Identifying the Common PartIdentifying the Common Part
class SalesPerson: Employee { double *comission_rate;// ... };
class Employee { char* name; short year_born; short department; int salary;public: void give_raise(
int how_much);// ... };
class Engineer: Employee { char* degrees;// ... };
C solution:struct Engineer { struct Employee E; char *degree; /* ….. */};
5
What is InheritanceWhat is Inheritance The BehaviorBehavior and the DataData associated with a
subclasssubclass are an extentionextention of the properties of the superclasssuperclass
EngineerEngineer and SalesPersonSalesPerson extends, each in its own way, the data and behavior of EmployeeEmployee
Identifying the EmployeeEmployee abstraction, helps us define more types easily
Class Employee
Class Manager
class Manager: Employee { char* degrees;// ... };
6
• Expanding the original class
• Specializing the original class
Inheritance ConceptInheritance Concept
RealNumber
ComplexNumber
ImaginaryNumber
Rectangle Triangle
Shape Point
Circle
realimag
real imag
3D-Point
7
Inheritance MechanismInheritance Mechanism
• A classclass may inheritinherit from a base classbase class, in which case the inheriting class is called a derived classderived class
• A classclass may override inherited methodsmethods (member functions), but cannot override inheritedinherited datadata
8
What is it Used For?What is it Used For?• Software reusabilitySoftware reusability
– Allows you to modify or extend a package somebody gave you without touching the package’s code
– Saves programming time
– Smaller programs
• Consistency of interfaceConsistency of interface – Saves user time
– Interface to similar objects is similar
– An overridden function must have the same return type
• PolymorphismPolymorphism – Different objects behave differently as a response to the
same message
Least important
More important
Most important
9
Inheritance Example
• TimeTime is the base class• ExtTimeExtTime is the derived class
ExtTime
Time
10
Class Class TimeTime Specification Specificationclass Time{protected:protected:
int hrs;int mins;int secs;
public: Time (int initH, int initM, int initS):
hrs(initH), mins(initM), secs(initS){};void Set (int h, int m, int s ){…};void Increment () {secs++;};void Print () const{
cout << hrs << “:” << mins << “:” << secs;};};
int main(){ Time *t = new Time(8,8,8); t->Print(); // 08:08:08}
11
Class Interface DiagramClass Interface Diagram
Protected data:
hrs
mins
secs
Set
Increment
Time
Class Time
12
Derived Class Derived Class ExtTimeExtTime #include#include “time.h” “time.h”
enum ZoneType {EST, CST, MST, PST, EDT, CDT, MDT, PDT};
class ExtTime: : publicpublic Time Time{ ZoneType zone;public: ExtTime (int initH, int initM, int initS, ZoneType initZ):Time(initH, initM, initS):Time(initH, initM, initS), zone(initZ){}; void Set (int h, int m, int s, ZoneType timeZone){ Time :: Set (h, m, s);Time :: Set (h, m, s); zone = timeZone;}; void Print ( )const { string zoneString[8] = {“EST”, “CST”, MST”,
“PST”, “EDT”, “CDT”, “MDT”, “PDT”} ;Time::Print ( );Time::Print ( );
cout << “ “ << zoneString[zone] << endl;}; };
13
Class Interface DiagramClass Interface Diagram
Protected data:
hrs
mins
secs
ExtTime class
Set
Increment
Time
Set
Increment
ExtTime
Private data:zone
14
Points of InterestPoints of Interest• We used public inheritancepublic inheritance, later we will talk about other
kinds of inheritance
• Constructors are not inheritedConstructors are not inherited. If we haven’t defined constructor for ExtTimeExtTime, then the compiler would try to generate an empty default constructor and fail in doing so since there is no default constructor of the base class TimeTime
• The initialization of the sub-object sub-object of the inherited class Time must be done in the initialization listinitialization list of the constructor of the derived class ExtTimeExtTime
ExtTime (int initH, int initM, int initS, ZoneType initZ):Time(initH, initM, initS), zone(initZ){};
class ExtTime: public Time{// …
15
Points of Interest cont.Points of Interest cont.• ExtTimeExtTime overrides PrintPrint method
• Since ExtTimeExtTime doesn’t override the IncrementIncrement method, the following calls the method from TimeTime class
• An overridden function can be called as follows:
class ExtTime: public Time{// …void Print ( )const; //overridden
ExtTime extTime = (8,8,8,EST);extTime.Increment();// …
// …Time::Print();cout << “ “ <<zoneString[zone]<<endl;
16
Working withWorking with ExtTimeExtTime
#include “exttime.h”
int main(){
ExtTime thisTime ( 8, 35, 0, PST );ExtTime thatTime (10, 10, 10, EST ); thatTime.Print( ); // outputs 10:10:10 EST
thatTime.Set (16, 49, 23, CDT) ; thatTime.Print( ); // outputs 16:49:23 CDT
thisTime.Increment ( ) ;thisTime.Increment ( ) ;thisTime.Print ( ); // outputs 08:35:02 PST
}
17
Access Control Over the MembersAccess Control Over the Members
• Two levels of access control over class members– class definitionclass definition– inheritance typeinheritance type
class Point{
protected:protected: int x, y;
public:public: void set(int a, int b);
}
class Circle : publicpublic Point{
… …
}
18
Access Control in Public inheritanceAccess Control in Public inheritance• privateprivate members of the base classbase class are notnot
accessible to the derived classderived class– Otherwise, privacy is completely violate
• publicpublic members of the base classbase class are accessible to anyone
• protectedprotected members of the base classbase class are accessible to derived classesderived classes only
class Time{proteced:
int hrs;int mins;int secs;
// ...
19
• Consider a class D derived from a base class B– With private inheritance (default mode), the public and protected
members of B can be used only by member functions and friends of D
– With protected inheritance, the public and protected members of B can be used only by member functions and friends of D and by member functions and friends of classes derived from D
– With public inheritance, the public and protected members of B can be used only by any function
Access Rights of Derived ClassesAccess Rights of Derived Classes
publicprotectedprivatepublicpublic
protectedprotectedprivateprotectedprotected
privateprivateprivateprivateprivate
publicpublicprotectedprotectedprivateprivate
Type of Inheritance
Acc
ess
Con
trol
for
Mem
ber
sAccess from external functions:
20
Class DerivationClass Derivation
A
B C D
class A {private: int private_a;protected: int protected_a;public: int public_a;};class B : private A {public: B(){ private_a = 2; // Error! protected_a = 2; public_a =2; };};class C : protected A {public: C(){ private_a = 3; // Error! protected_a = 3; public_a = 3; };};class D : public A {public: D(){ private_a = 4; // Error! protected_a = 4; public_a =4; };};
int main(){
B b; C c; D d;b.public_a=10; // Error!c.public_a=10; // Error!d.public_a=10;return 0;
}
21
class A {public:
A ( ) {cout<< “A::A()”<<endl;}A (int a){ cout<<“A::A(int a)”<<endl;}
}
Constructor Rules for Derived Constructor Rules for Derived Classes Classes
class C : public A {
public:
C (int c): A(c)C (int c): A(c){
cout<<“C::(int c)”<<endl;}
}
Option 1:
class C : public A {
public:
C (int c)C (int c){
cout<<“C::(int c)”<<endl;}
}
Option 2:
C test(1); // A::A(int a) // C::C(int c)
C test(1); // A::A() // C::C(int c)
22
Is-A RelationshipIs-A Relationship
• Derived class is ais a (more specialized) version of the base class:– Manager is an Employee– ExtTime is a time– Rectangle is a Shape
• Thus, any function taking the class B (base class) as an argument, will also accept class D (derived class from B)
class Stack {...}; int SumAndPop(Stack& s){...}class MultiStack: public Stack { public: void popk(int k) {...}};
int main(){ MultiStack multiStack; int a = SumAndPop(multiStack); //...}
23
Is-A Relationship cont.Is-A Relationship cont.
Person p;Worker w;
p.GetName(); // OKw.GetName(); // OK
p.CalculateSal(); // ERROR!w.CalculateSal(); // ok
Class Person
Class Worker
nameGetName()
salaryCalculateSal()
WorkerWorker is a PersonPerson but not vice-versa!
24
SummarySummary• What we have seen so far
– Inheritance for code reusecode reuse reasons
– Reflects a relationship of Is-AIs-A
– Inheritance means that the derivedderived inherits its base classbase class characteristics
– The derived classderived class can add to this characteristics of its own
Class Person
Class Worker
nameGetName()
salaryCalculateSal()
25
Summary cont.Summary cont.– We can invoke all inheritedinherited characteristics through the
derivedderived
– For instance, we can ask the worker what is his name, even though he does not implement such a method
– The compiler resolves the call to Person::GetName()
– If we implement such a method at the Worker class, the compiler will call to Worker::GetName()
– ProtectedProtected access keyword has been introduced
Worker w;w.GetName();
27
Lets Continue to Polymorphic Lets Continue to Polymorphic InheritanceInheritance
• Suppose we have a container of Employees• We would like to iterate over all employees, without knowing which
specific kind they are, and ask them to calculate their salary (call their CalcSalary() method)
• Each type has its own calculation algorithm, based on different considerations
• Each object will invoke its relevant CalcSalary(), depending on its type
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
28
ExampleExample
We want each element in the container to call its own CalcSalary() method as a function of the real object
Employee Employee::CalcSalary()
SalesPerson SalesPerson::CalcSalary()
Executive Executive::CalcSalary()
Administrative Administrative::CalcSalary()
Executive
Administrative
Administrative
Executive
Sales Person
Employee* employees[100];
29
Static and dynamic bindingStatic and dynamic binding• In object-oriented programming languages
in most cases the variables are bound to a specific type at compile time– Static binding
• Dynamic binding– The type of the variable can change at run time– Using pointers to classes related by inheritance
– Can be dangerous in some cases
Executive exec;Employee* emp = &exec;
30
ExampleExample
class Employee { public:
void CalcSalary ();};class SalariedEmployee: public Employee{ public:
void CalcSalary ();};
Employee *ep;ep = new SalariedEmployee;ep->CalcSalary();
The function in EmployeeEmployee is called!
• To avoid that we have to declare CalcSalary() as a virtual function virtual function (virtual is a special keyword)
31
Virtual FunctionsVirtual Functions• Definition:
– Member function prefaced by the virtual specifier.– Compiler generates the code that will select the appropriate
function at runtime• virtualvirtual specifier needs to appear in the base class only
– However, typically specified also in subclasses
class Employee { public:
virtual void CalcSalary ();};
class SalariedEmployee:public Employee{ public:
virtual void CalcSalary ();};
32
ExamplesExamples
• Any non-static member function except a constructor can be virtual
• Virtual functions can also be friends of other classes
• Some compilers require the class destructor to be virtual if a class contains any virtual functions
Employee *p0 = new Employee;Employee *p1 = new SalariedEmployee;p0->CalcSalary(); // calls Employee::CalcSalary()p1->CalcSalary(); // calls SalariedEmployee::CalcSalary()
33
Virtual FunctionsVirtual Functions
• Calls on object itself resolved statically - b.y();
• If non-virtual there, resolve statically - ap->x();
• If virtual there, resolve dynamically - ap->y();
• Caller can force static resolution of a virtual function - ap->A::y();
int main () { B b; A *ap = &b; B *bp = &b; b.x (); b.y (); bp->x (); bp->y (); ap->x (); ap->y (); ap->A::y(); return 0;};
Output:B:xB:yB:xB:yA:xB:yA:y
class A {public: void x() {cout<<"A:x";}; virtual void y() {cout<<"A:y";};};
class B : public A {public: void x() {cout<<"B:x";}; virtual void y() {cout<<"B:y";};};
34
Combinations of virtual and non-Combinations of virtual and non-virtual functionsvirtual functions
• Non-virtual function can call virtual function class Employee { public:
void Display() {CalcSalary();};virtual void CalcSalary ();
};
class SalariedEmployee:public Employee{ public:
void Display() {CalcSalary();};virtual void CalcSalary ();
};
Employee *p0 = new SalariedEmployee;p0->Display(); // calls SalariedEmployee::CalcSalary();
35
Combinations of virtual and non-Combinations of virtual and non-virtual functionsvirtual functions
• Non-virtual function can call virtual function class Employee { public:
virtual void Display() {CalcSalary();};void CalcSalary ();
};
class SalariedEmployee:public Employee{ public:
virtual void Display() {CalcSalary();};void CalcSalary ();
};
Employee *p0 = new SalariedEmployee;p0->Display(); // calls Employee::CalcSalary();
36
Common InterfaceCommon Interface• Virtual functions in the base classbase class provide
common interfaceinterface for all of its derived classes
class Employee { public:
long GetDepartment();long GetId();virtual void Display();virtual void Input();virtual void CalcSalary();
private:long id;long deptNum;
};
37
ExampleExampleclass Polygon { protected: int width, height; public:
void setValues (int a, int b){ width=a; height=b; }virtual int area(){ retuen 0; }
};
class Rectangle: public Polygon { public: int area () { return (width * height); }};
class Triangle: public Polygon { public: int area () { return (width * height / 2); } };
38
Example (cont.)Example (cont.)
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = ▭
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl; // 20
cout << ppoly2->area() << endl; // 10
return 0;
}
39
Virtual DestructorsVirtual Destructors• Destructor preceded by the virtual specifier
– Correct destructor must be called• It is recommended that any class containing any class containing
virtual functions should also have a virtual virtual functions should also have a virtual destructordestructor
• BookItem needs a separate destructor to de-allocate the storage for title
class Item {
public:
virtual ~Item();
//...
};
class BookItem : public Item{
public:
virtual ~BookItem();
private:
char * title;
};
40
Pure VirtualPure Virtual
• The Employee can define this method at the base class as pure virtualpure virtual :
virtual int Employee::CalcSalary() = 0;
Meaning,– We cannot instantiate an object of this class – it is
said to be an Abstract ClassAbstract Class
– It wants all inheriting classes to implement their own implementation
– But we still can have pointers
41
ExampleExampleclass Polygon { protected: int width, height; public:
void setValues (int a, int b){ width=a; height=b; }
virtual intvirtual int area()=0; area()=0; };
class Rectangle: public Polygon { public: int area () { return (width * height); }};
class Triangle: public Polygon { public: int area () { return (width * height / 2); } };
42
Virtual FunctionsVirtual Functionsclass A {public: virtual void x() = 0; virtual void y() = 0;};class B : public A {public: virtual void x();};class C : public B {public: virtual void y();};int main () { A * ap = new C; ap->x (); ap->y (); delete ap; return 0;};
• A is an Abstract Base ClassAbstract Base Class– Declares pure virtual functionspure virtual functions (=0)
• Derived classes override pure virtual methods– B overrides x(), C overrides y()
• Can’t instantiate class with declared or inherited pure virtual functions– A and B are abstract, C can be
created• Can still have a pointer to an
abstract class type– Useful for polymorphism
43
Static Binding Vs. Dynamic BindingStatic Binding Vs. Dynamic Binding
• Static Binding– Function call is resolved during compile time
– Call fixed value
• Dynamic Binding– During compile time we cannot know what address to jump to
– It needs to be resolved during run-time
– Depending on the type of the actual object
• This information is accessed via virtual pointer– Each object holds
• And via virtual table– Each class maintains
44
Dynamic Binding - ImplementationDynamic Binding - ImplementationExecutive
Administrative
Administrative
Executive
Sales Person
Executive Virtual Table
Sales Person Virtual Table
Executive::CalcSalary()
SalesPerson::CalcSalary()
Employee* employees[100];
45
Summary: Tips on PolymorphismSummary: Tips on Polymorphism• Push common code and variables up into base base
classesclasses• Use public inheritancepublic inheritance for polymorphism• Polymorphism depends on dynamic typing
– Use a base-class pointerbase-class pointer or reference if you want polymorphism
– Use virtual member functionsvirtual member functions for dynamic overriding
• Use private inheritanceprivate inheritance only for encapsulation• Use abstract base classesabstract base classes to declare interfaces• Even though you don’t have to, label each virtual
method (and pure virtual method) in derived classes
47
Let's recallLet's recall• What we have seen so far
– Polymorphic inheritance• For defining generic interface
• Accessing the concrete implementations via this interface
• The compiler implements code, which extracts during Run-Time the needed calling address
• Through a virtual pointer– Which usually point at the actual object
• And through a virtual table– Which holds the addresses of the virtual functions
48
Construction and DestructionConstruction and Destruction
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
• Let us recall the construction order and functionality – What is the order of “things”
• Let us see what happens during destruction– What is the order of “things”
• Can a destructor be virtual? Does it need to be virtual? When?
49
Multiple InheritanceMultiple Inheritance
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
Class Student
v. M()
Class Metargel
v. CalcSalary()v. M()
Class Person
• Sometimes it is desirable for a derived class to inherit features from more than one base class
• How is this represented in memory? What is the layout of the instance?
• Can you think of problems using this?
50
SyntaxSyntax
Teaching Assistant maintains the attributes and the methods associated with both base classes Student, and Employee
class Metargel : public Student, public Employee{ // …}
51
Polymorphic AssignmentPolymorphic Assignment
Metargel * myMetargel = new Metargel;
Employee * E = myMetargel;
//Legal as a Teaching Assistant
//is-an Employee
Student * S = myMetargel;
//Legal as a Teaching Assistant
//is-a Student
52
Problems with Multiple InheritanceProblems with Multiple Inheritance• Name Ambiguity:Name Ambiguity:
– Similar names can be used for different operations in the base classes • e.g. an employee might have an id_number and a student might also have
an id_number field.
– Both base classes might have a similar get_id() method– The compiler cannot determine which version to use in the Metargel
class: the get_id() in the Employee class or the get_id () in the Student class
• A common misuse of multiple inheritance is using it as compositioncomposition rather than specializationspecialization (is-a): – The following is incorrectincorrect:
class car: public Engine, public Transmission, public Wheels
53
Name AmbiguityName Ambiguity
Solution 1:
Use a fully qualified function name:
Metargel * myMetargel = new Metargel;
cout << “ The TeachingAssistant is” <<
myMetargel -> Employee::get_id() << “\n”;
54
Name AmbiguityName AmbiguitySolution 2:Redefine the ambiguous function in the new class and hide the qualified name in a method body:
class Metargel : public Student, public Employee{
public: string get_id();public: string student_id();
}string Metargel ::get_id(){
return Employee::get_id();}
string Metargel ::student_id(){
return Student::get_id();}
55
Virtual Inheritance - MotivationVirtual Inheritance - Motivation
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
Class Student
v. M()
Class Metargel
v. CalcSalary()v. M()
Class Person Class Personm_namem_name
• What if class student and class Employee both inherit from Person?
• How can this be dealt with?
56
Replicated Base ClassesReplicated Base Classes• The same class can not be directly inheritedcan not be directly inherited more
than once
• Base classes might be inherited indirectlymight be inherited indirectly more than once – due to a class inheritance hierarchy
• In our example suppose the following:class Employee : public Person {..}
class Student : public Person {..}
class Metargel : public Student, public Employee {..}
• Attributes from the Person class get inherited twice!– Metargel will have two m_name fields
57D
B
Replicated InheritanceReplicated Inheritance• Recall that replicated inheritance does not share the same
common grandparent even if they both derive from the same grandparent!
• If we have code like this in C++:class A { … };
class B: public A { … };
class C: public A { … }; /* Derives from A but it isn’t shared!*/
class D: public B, public C { … };
• This gives us the following situation:
A
B C
A
D
A* a; B* b; C* c; D* d;
b = d; // ok
c = d; // ok
a = b; // ok
a = c; // ok
a = d; //error ambiguous
A
C
A
58
Virtual Inheritance Virtual Inheritance Single instance within layout
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
Class Student
v. M()
Class Metargel
v. CalcSalary()v. M()
Class Person
59
Virtual Base ClassesVirtual Base Classes
• To merge any common base classes into one single copy the inheritance should be written as virtualvirtual:
class Employee: virtual public Person {..}
class Student: virtual public Person {..}
class TeachingAssistant : public Student, public Employee {..}
60
Virtual InheritanceVirtual Inheritance
• Standard base classes– A members appear twice in D
• Virtual base classes class B : public virtual A { … }– Avoid duplication of base
class members– Require additional pointers so
that A part of B, C parts of object can be shared
D
B
A
B C
D
A
C
61
Virtual Base ClassesVirtual Base Classes Metargel * myMetargel = new Metargel; Student * s = myMetargel; // Legal due to is-a
// relationship Person * p = s; // Legal due to is-a relationship Employee * e = myMetargel;// Legal due to is-a
// relationship Person * p1 = e; // Legal due to is-a relationship
Person * p2 = myMetargel; // Legal only if Virtual // Inheritance is used so that the compiler knows which // version of person to use, error otherwise
62
Summary - Multiple InheritanceSummary - Multiple Inheritance• It is recommended to keep multiple inheritance
to minimal usage– Due to complexity, which may arise– Due to misusage– You may use it, but please use it with care
• Recommended to use as many as possible abstract classesabstract classes, and not multiple inheritancemultiple inheritance
• Make sure this really models your problem domain well