Download presentation
Presentation is loading. Please wait.
Published byBrianna Fitzgerald Modified over 8 years ago
1
1 Chapter 7 INHERITANCE
2
2 Outlines 7.1 Fundamentals of Inheritance 7.2 The protected Access Specifier 7.3 Constructing and Destroying Derived Classes 7.4 Multiple Inheritance 7.4.1 Direct Multiple Inheritance 7.4.2 Indirect Multiple Inheritance 7.5 Dominating and Overriding Base Class Members
3
3 Introduction Code reusability is a very important programming concept, and C++ facilitates this concept more efficiently than C. Inheritance is one of the most powerful OOP tools in the implementation of code reusability in C++. When using inheritance, a new class can be created by establishing parent-child relationships with existing classes.
4
4 7.1 FUNDAMENTALS OF INHERITANCE Inheritance is a relationship between classes in which one class inherits the properties (attributes and behaviors) of another class. Implementing inheritance promotes code reusability because new classes are created from existing classes. Inheritance is also called derivation or an is-a relationship. It enables a hierarchy of classes to be designed. The hierarchy begins with the most general class and moves to more specific classes.
5
5 By implementing inheritance, data members and member functions from one class (higher in hierarchy) can become properties (members) of another class (lower in hierarchy) without coding them explicitly within this class. A class that is inherited (higher in hierarchy) is called a base class or a parent class. A class (lower in hierarchy) that inherits properties of another class (base class) is called a derived class or child class.
6
6 Inheritance hierarchy
7
7 The base class defines all properties that can be inherited by any derived class, as well as some non ‑ inheritable private properties of its own. Inheritance continues with the definition of a derived class that contains the properties inherited from the base class and some other properties that are specific to the derived class.
8
8 Formulation class derived_class_name:access_specifier base ‑ class ‑ name { //specific properties of the derived ‑ class }
9
9 class Amplifier { //base class public: float gain;//gain float involt, outvolt;//input and output voltag void setGain();//Sets gain void setInvolt();//Sets input voltage void get0utvolt();//Computes and displays output //voltage }; class OPAMP : public Amplifier { //derived class private: float rin;//input resistor float rout;//feedback resistor public: void setRes();//Sets resistors float getGain(); // Computers and returns gain };
10
10 Type of inheritance Single inheritance : a class is derived from only one base class (a child class has only one parent class). –A parent class, however, can have many child classes.
11
11 Multiple inheritance, a class can have more than one parent class. Multiple inheritance is discussed in Section 7.4.
12
12 access specifier that precedes a base class name defines the status of the members inherited from the base class within the derived class. The private access specifier means that all members inherited from the base class will be private in the derived class. The access specifier is public, all inherited members will have the same status in the derived class as the status these members have in the base class.
13
13 Default When inheriting from a base class, the default access is private. It can therefore be omitted in the header of a derived class definition as follows: class OPAMP : Amplifier { //members specific to OPAMP };
14
14 The members that are inherited from the Amp1ifier class are private to the 0PAMP class in this example. Any class that is derived from 0PAMP cannot inherit these members.
15
15 The following data members and functions cannot be inherited from a base class: –private members (private data members and private member functions) –Constructor and destructor functions –friend functions –static functions –Operator functions that overload the assignment operator
16
16 7.2 THE protected ACCESS SPECIFIER The protected access specifier is used only when implementing inheritance. To enable a derived class to access members of a base class while keeping these members hidden from the rest of the program. Members of a base class that are specified as protected can be accessed directly by –Any non static member function of a base class –Any friend function of a base class –Any non static member function of a class derived from the base class –Any friend function of a class derived from the base class
17
17 class Amplifier (//base class private: float involt, outvolt;//input and output voltage protected: float gain;//gain public:.. void setGain();//Sets gain void setInvolt();//Sets input voltage float getOutvolt();//Computes and displays output voltage class OPAMP : public Amplifier (//derived class private: float rin;//input resistor float rout;//feedback resistor public: void setResist();//Sets resistors float getGain();//Computes and returns gain
18
18 When defining a derived class, protected can also be used to specify a type of inheritance. The type of inheritance is specified by the access specifier (private,protected, or public), which precedes a base class name in the header of a derived class. All public and protected members inherited from the base class with the protected access specifier will be protected in the derived class. Table 7.2 shows the three types of inheritance and how each type affects the status of inherited members within a derived class.
19
19
20
20
21
21 7.3 CONSTRUCTING AND DESTROYING DERIVED CLASSES Every base and derived class in an inheritance hierarchy should have its own constructor and destructor functions. Constructors and destructors cannot be inherited. When instantiating an object of a derived class, constructors of all of its parent classes are executed prior to the derived class constructor. This is understandable because when creating a child, all of its parents have to be created before the child can be created. The constructor functions, therefore, are executed in the order of derivation within the inheritance hierarchy.
22
22
23
23 Parameters list If a base class constructor has arguments, these arguments also have to be added to the argument list of any class derived from this base class. When instantiating an object of the derived class, all of the arguments required by the base constructor and derived constructor are first passed to the derived constructor. The derived constructor then passes appropriate arguments along to the base class constructor. derived_class(arg_list1):base class(arg_list2) { //body of derived class constructor }
24
24
25
25 //PROG7_1: Program demonstrates the mechanisms of constructing // and destroying objects of derived classes. #include using namespace std; class Amplifier { //base class float involt; //input voltage float outvolt; //output voltage protected: float gain; public: Amplifier(float=0, float=1); //constructor ~Amplifier(){cout<<"Destroying amplifier!"<<endl;} //destructor void setInvolt(float inv) { involt=inv; } float getOutvolt(){outvolt=involt*gain; return outvolt;} }; Amplifier::Amplifier(float inv, float g) //base constructor { cout<<"Constructing amplifier!"<<endl; involt=inv; gain=g; outvolt=involt*gain; }
26
26 class OPAMP_NI:public Amplifier { //derived class float rin; //input resistor float rf; //feedback resistor public: OPAMP_NI(float=0, float=1, float=0, float=0); //constructor ~OPAMP_NI(){cout<<"\nDestroying OPAMP!"<<endl;} //destructor void setRes(float r1, float r2){rin=r1; rf=r2;} float getGain(){gain=1+rf/rin; return gain;} }; OPAMP_NI::OPAMP_NI(float v, float a, float r1, float r2):Amplifier(v, a) { //derived constructor cout<<"Constructing OPAMP!"<<endl; rin=r1; rf=r2; }
27
27 int main() { OPAMP_NI amp1; //derived class's object float r1, r2, volt; cout "; cin>>r1>>r2; amp1.setRes(r1,r2); cout "; cin>>volt; amp1.setInvolt(volt); cout<<setiosflags(ios::fixed)<<setprecision(2); cout<<"\n\t\tGain = "<<amp1.getGain( )<<endl; cout<<"\t\tOutput Voltage = "<<amp1.getOutvolt()<<" [V]\n"; return 0; }
28
28
29
29 7.4 Multiple inheritance When implementing multiple inheritance, a class can be derived directly or indirectly from as many parent classes as necessary. There are two types of multiple inheritance: – Direct multiple inheritance – Indirect multiple inheritance
30
30 7.4.1 DIRECT MULTIPLE INHERITANCE When implementing direct multiple inheritance, a derived class can directly inherit more than one base class. To define a class that directly inherits multiple base classes, the general format is class Derived class:access specifier Base1_class, access specifier Base2_class,..., access specifier BaseN class { //body of derived class };
31
31
32
32 //PROG7_2: Program demonstrates direct multiple //inheritance. #include using namespace std; class Resistor { //base class # 1 protected: double res; //resistance public: Resistor(double r) { res=r; } void setRes() { cout >res; } double getRes() { return res; } };
33
33 class Capacitor { //base class # 2 protected: double cap; //capacitance public: Capacitor(double c) { cap=c; } void setCap() { cout >cap; } double getCap() { return cap; } };
34
34 class Low_Pass:public Resistor,public Capacitor { //derived class double frq_cut; //cutoff frequency public: Low_Pass (double, double); //derived constructor void setFreq() { frq_cut=1/(res*cap); } double getFreq() { return frq_cut; } }; Low_Pass::Low_Pass(double r, double c):Resistor(r),Capacitor(c) { //derived constructor with initialization list setFreq(); }
35
35 int main() { Low_Pass filter(1000, 0.00000047); cout<<"Low-Pass Filter:"<<endl; cout<<"\tR = "<<filter.getRes()<<" ohms"<<endl; cout<<"\tC = "<<filter.getCap()<<" F"<<endl; cout<<"\tCutoff Frequency = "<<filter.getFreq()<<" rad/s"; cout<<"\n\nAfter changing R and C:"<<endl; filter.setRes(); filter.setCap(); filter.setFreq(); cout<<"\tCutoff Frequency = "<<filter.getFreq()<<" rad/s"; return 0; }
36
36
37
37
38
38
39
39 7.4.2 INDIRECT MULTIPLE INHERITANCE A class can indirectly inherit members of another class through its base class. The original base class in this case is derived from another base/parent class, creating a multilevel inheritance hierarchy.
40
40 //PROG7_3: Program demonstrates indirect multiple inheritance. #include using namespace std; class RC_Circuit { //base class protected: double res; //resistance double cap; //capacitance public: RC_Circuit(double r, double c) { res=r; cap=c; } void setRes() { cout >res; } double getRes() { return res; } void setCap() { cout >cap; } double getCap() { return cap; } }; class Filter:public RC_Circuit { //derived classs #1 protected: double frq; //frequency public: Filter(double r, double c, double f):RC_Circuit(r,c){frq=f;} double getFreq() { return frq; } };
41
41 class Low_Pass:public Filter { //derived class #2 double frq_cut; //cutoff frequency public: Low_Pass (double, double, double); void setCutoff() { frq_cut=1/(res*cap); } double getCutoff() { return frq_cut; } bool isPreserved(); }; Low_Pass::Low_Pass(double r, double c, double f):Filter(r,c,f) { setCutoff(); } bool Low_Pass::isPreserved() { return ((frq<=frq_cut)? true : false); }
42
42 int main() { Low_Pass filter(1000, 0.00000047, 2500); cout<<"Low-Pass Filter:"<<endl; cout<<"\tR = "<<filter.getRes()<<" ohms"<<endl; cout<<"\tC = "<<filter.getCap()<<" F"<<endl; cout<<"\tCutoff Frequency = "<<filter.getCutoff()<<" rad/s"; if(filter.isPreserved()) { cout<<"\n\tFrequency = "<<filter.getFreq(); cout<<" rad/s is preserved."<<endl; } else { cout<<"\n\tFrequency = "<<filter.getFreq(); cout<<" rad/s is attenuated."<<endl; }
43
43 cout<<"\n\nAfter changing R and C:"<<endl; filter.setRes(); filter.setCap(); filter.setCutoff(); cout<<"\tCutoff Frequency = "<<filter.getCutoff()<<" rad/s"; if(filter.isPreserved()) { cout<<"\n\tFrequency = "<<filter.getFreq(); cout<<" rad/s is preserved."<<endl; } else { cout<<"\n\tFrequency = "<<filter.getFreq(); cout<<" rad/s is attenuated."<<endl; } return 0; }
44
44
45
45 7.5DOMINATING AND OVERRIDING BASECLASS MEMBERS When inheriting from a base class, some inherited members can be overridden and the others dominated by members of a derived class. In either case, members inherited from the base class have the same name (identifier) as members of the derived class that override or dominate the inherited members. a data member of a derived class dominates a data member inherited from a base class that uses the same identifier.
46
46 //PROG7_4: Program demonstrates the principles // of dominating and // overriding inherited members. #include using namespace std; class Resistor { //base class public: float r; //resistance Resistor(float x = 0) { r=x; } void getVal() { cout<<"R = "<<r<<endl; } };
47
47 class Circuit:public Resistor { //derived class public: float r; //resistance double c; //capacitance Circuit(float x, double y):Resistor(330) { r=x; c=y; } void getVal() { cout<<"R = "<<r<<" C = "<<c<<endl; } };
48
48 int main() { Resistor res1(470); Circuit cir1(200, 0.0001), cir2(1000, 0.0005); cout<<"\t\tAccessing data members:\n\n"; cout<<"res1.r = "<<res1.r<<endl; cout<<"cir1.r = "<<cir1.r<<endl; cout<<"cir2.r = "<<cir2.r<<endl; cout<<"cir1.Resistor::r = “<<cir1.Resistor::r<<endl; cout<<"cir2.Resistor::r = "<<cir2.Resistor::r<<endl;
49
49 Resistor res2=cir2; cout<<"res2.r = "<<res2.r<<endl; cout<<"\n\t\tExecuting member functions:\n\n"; res1.getVal(); cir1.getVal(); cir1.Resistor::getVal(); cout<<"\n\t\tUsing a base class pointer:\n\n"; Resistor *rptr; rptr=&res1; rptr->getVal(); rptr=&cir1; rptr->getVal(); return 0; }
50
50 The base class name followed by the scope resolution operator (::) is used only in cases in which it is necessary to distinguish inherited members from the members with the same name declared within the derived class.
51
51
52
52 To determine which of these two functions will be invoked when using cir1.getVa 1( )(line 32), C++ uses the following principle: a function defined within a derived class over rides a function with the same signature that is inherited from a base class.
53
53
54
54
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.