Inheritance
Inheritance
Inheritance
• An important feature of OOP is reusability. It not only saves time and
money but also reduces frustration and increase reliability.
• C++ classes can be reused in several ways. Once a class has been
written and tested, it can be adapted by other programmers to suit
their requirements.
• New classes can be created which reuse the properties of the existing
ones.
• The mechanism of deriving a new class from an old one is called
inheritance. The old class is referred to as the base class and the new
class is called the derived class or subclass.
• The derived class inherits some or all of the traits from the base class.
• A class can inherit properties from more than one class or from more
than one level.
• A derived class with only one base class is called single inheritance
and one with several base classes is called multiple inheritance.
• Also, the traits of one class may be inherited by more than one class.
This process is called hierarchical inheritance.
• The mechanism of deriving a class from another ‘derived class’ is
known as multilevel inheritance.
Types of Inheritance
Defining Derived Classes
• A derived class can be defined by specifying its relationship with the base
class in addition to its own details. The general form of defining a derived
class is:
• The colon indicates that the derived-class-name is derived from the base-
class-name.
• The visibility mode is optional and, if present, may be either private or
public.
• The default visibility-mode is private. Visibility mode specifies whether the features of the
base class are privately derived or publicly derived.
• Examples:
class ABC: private XYZ //private derivation
{
members of ABC
};
class ABC: public XYZ //public derivation
{
members of ABC
};
class ABC: XYZ //private derivation by default
{
members of ABC
};
• When a base class is privately inherited by a derived class, ‘public
members’ of the base class become ‘private members’ of the derived
class.
• Therefore, public members of the base class can only be accessed by the
member functions of the derived class.
• When the base class is publicly inherited, ‘public members’ of the base
class become ‘public members’ of the derived class.
• Therefore, they are accessible to the objects of the derived class.
• In both the cases, the private members are not inherited and therefore,
the private members of a base class will never become the members of
its derived class.
• In inheritance, some of the base class data elements and member
functions are inherited into the derived class.
Single Inheritance: Public
#include<iostream>
using namespace std;
class B
{
int a; //private; not inheritable
public:
int b; //public; ready for inheritance
void get_ab();
int get_a(void);
void show_a(void);
};
class D: public B //public derivation
{
int c;
public:
void mul(void);
void display(void);
};
void B :: get_ab()
{
a = 5; b = 10;
}
int B :: get_a()
{
return a;
}
void B :: show_a()
{
cout << “a = ” << a << “\n”;
}
void D :: mul()
{
c=b*get_a();
}
void D :: display() d.b = 20;
{ d.mul();
cout << “a = ” << get_a() << “\ d.display();
n”;
cout << “b = ” << b << “\n”; return 0;
cout << “c = ” << c << “\n”; }
}
OUTPUT:
int main()
a=5
{
a=5
D d; b = 10
d.get_ab(); c = 50
d.mul(); a=5
d.show_a(); b = 20
d.display(); c = 100
Adding more members to a class (by public
derivation)
Single Inheritance: Private
#include<iostream>
using namespace std;
class B
{
int a; //private; not inheritable
public:
int b; //public; ready for inheritance
void get_ab();
int get_a(void);
void show_a(void);
};
class D: private B //public derivation
{
int c;
public:
void mul(void);
void display(void);
};
void B :: get_ab()
{
cout <<“Enter values for a and b:”;
cin>>a>>b;
}
int B :: get_a()
{
return a;
}
void B :: show_a()
{
cout << “a = ” << a << “\n”;
}
void D :: mul()
{
get_ab();
c=b*get_a();
}
void D :: display() d.mul();
{ d.display();
show_a();
cout << “b = ” << b << “\n”; return 0;
cout << “c = ” << c << “\n”; }
}
OUTPUT:
int main()
Enter values for a and b: 5 10
{
a=5
D d;
b = 10
//d.get_ab(); won’t work
c = 50
d.mul(); Enter values for a and b: 12 20
//d.show_a(); won’t work a = 12
d.display(); b = 20
//d.b = 20; won’t work c = 240
Making a Private member
Inheritable
• C++provides a third visibility modifier, protected, which serve a limited
purpose in inheritance.
• A member declared as protected is accessible by the member functions
within its class immediately derived from it.
• It cannot be accessed by the functions outside these two classes.
• When a protected member is inherited in public mode, it becomes
protected in the derived class too and therefore is accessible by the
member functions of the derived class. It is also ready for further
inheritance.
• A protected member inherited in the private mode becomes private in
the derived class. It is available to the member functions of the derived
class but it is not available for further inheritance.
Effect of inheritance on the visibility of
members
• The keywords private, protected and public may appear in any order and any
number of times in the declaration of a class. For example:
class beta
{
protected:
…..
public:
…..
private:
…..
public
…..
};
Is a valid class definition.
• It is also possible to inherit a base class in protected mode (known as
protected derivation).
• In protected derivation, both the public and protected members of
the base class become protected members of the derived class.
• The various functions that can have access to the private and
protected members of a class are:
1. A function that is a friend of the class.
2. A member function of a class that is a friend of the class.
3. A member function of a derived class.
Access mechanism in
classes
Multilevel Inheritance
• In multilevel inheritance, a class is derived from another derived class.
• The class A serves as a base class for the derived class B, which in turn
serves as a base class C.
• The class B is known as intermediate base class since it provides a link
for the inheritance between A and C. The chain ABC is known as
inheritance path.
• A derived class with multilevel inheritance is declared as follows:
class A {…..}; // Base class
class B:public A {…..}; // B derived from A
class C:public B {…..}; // C derived from B
• This process can be extended to any number of levels.
• Consider a simple example where the test results of a batch of
students are stored in different classes.
• Class student stores the roll-number, class test stores the marks
obtained in two subjects and class result contains the total marks
obtained in the test.
• The class result can inherit the details of the marks obtained in the
test and the roll-number of students through multilevel inheritance.
class student void student::put_number ()
{ {
cout <<“Roll Number:”<< roll_number
protected: <<“\n”; }
int roll_number; class test: public student
public: {
void get_number (int); protected:
void put_number (void); float sub1;
float sub2;
};
public:
void student::get_number (int a)
void get_marks (float, float);
{ roll_number = a; } void put_marks (void);
};
void test:: get_marks (float x, class result : public test
float y) { float total;
{ public:
sub1 = x; void display (void);
sub2 = y; };
} void result:: display (void)
void test:: put_marks () { total = sub1 + sub2;
{ put_number ();
cout << “Marks in SUB1 = ” << put_marks ();
sub1 <<“\n”; cout << “Total = ” << total
<<“\n”;
cout << “Marks in SUB2 = ” <<
sub2 <<“\n”; } }
int main Output:
{ Roll Number: 111
result student1; Marks in SUB1 = 75
Marks in SUB2 = 59.5
student1.get_number (111); Total = 134.5
student1.get_marks (75.0,
59.5);
student1.display ();
return 0;
}
Multiple Inheritance
• A class can inherit the attributes of two or more classes. This is known
as multiple inheritance.
• Multiple inheritance allows us to combine the features of several
existing classes as a starting point for defining new classes.
• The syntax of a derived class with multiple base classes is as follows:
class D: visibility B-1, visibility B-2 …
{
…..
….. (Body of D)
…..
};
where, visibility may be either public or private. The base classes are
separated by commas.
class M class P: public M, public n
{ }
protected: public:
int m; void display ();
public: };
void get_m (int); void M:: get_m(int x)
}; { m = x; }
class n void N:: get_n(int y)
{ { n = y; }
protected: void P:: display ()
int n; { cout << “m = ” << m << “\n”;
public: cout << “n = ” << n << “\n”;
void get_n (int); cout << “m*n = ” << m*n << “\n”;
}; }
int main Output:
{ m = 10
P p; n = 20
m*n = 200
p.get_m (10);
p.get_n (20);
p.display ();
return 0;
}
Ambiguity Resolution in Inheritance
• Occasionally, we may face a problem in using the multiple inheritance
when a function with the same name appears in more than one base class.
• Consider the following two classes:
class M
{
public:
void display (void)
{
cout << “ Class M\n”;
}
};
class N
{
public:
void display (void)
{
cout << “ Class N\n”;
}
};
• Which display() function is used by the derived class when we inherit
these two classes?
• This problem can be solved by defining a named instance within the
derived class, using the class resolution operator with the function as
shown below:
class P: public M, public N
{
public:
void display (void) // overrides display of M and N
{
M:: display ();
}
};
• We can now use the derived class as follows:
int main ()
{
P p;
p.display ();
}
• Ambiguity may arise in single inheritance applications.
class A
{
public:
void display (void)
{
cout << “ A\n”;
}
};
class B: public A
{
public:
void display (void)
{
cout << “ B\n”;
}
};
• In this case, the function in the derived class overrides the inherited
function and, therefore, a simple call to display() by B type object will
invoke function defined in B only.
• We may invoke the function defined in A by using scope resolution
operator to specify the class.
• Example:
int main ()
{
B b; // derived class object
b.display (); // invokes display () in B
b.A::display (); // invokes display () in A
b.B::display (); // invokes display () in B
return 0;
}
Hierarchical Inheritance
• Many programming problems can be cast into a hierarchy where
certain features of one level are shared by many others below that
level.
• For example, classification of students in a university as shown below:
• Another example could be that of accounts in a commercial bank as
shown below:
Hybrid Inheritance
• There could be situations where we need to apply two or more types
of inheritance to design a program.
• As an example, consider the case of processing the student results
where we have to give weightage to sports before finalizing the
results.
• The weightage for sports is stored in a separate class called sports.
• The new inheritance relationship between the various classes would
be as shown:
#include<iostream>
Using namespace std;
class student
{
protected:
int roll_number;
public:
void get_number(int a)
{
roll_number = a;
}
void put_number (void)
{
cout << “Roll No: ” << roll_number<<“\n”;
}
};
class test : public student
{
protected:
float part1, part2;
public:
void get_marks(float x, float y)
{
part1 = x; part2 = y;
}
void put_marks (void)
{
cout << “Marks obtained: ” << “\n”
<< “Part1 = ” << part1 <<“\n”
<< “Part2 = ” << part2 <<“\n”
}
};
class sports
{
protected:
float score;
public:
void get_score(float s)
{
score = s;
}
void put_score (void)
{
cout << “Sports wt: ” << score << “\n\n”;
}
};
class result : public test, public sports
{
protected:
float total;
public:
void display (void);
};
void result :: display (void)
{
total = part1 + part2 + score;
put_number ();
put_marks ();
put score ();
cout << “Total Score: ” << total << “\n”;
}
int main ()
{
result student1;
student1.get_number (1234);
student1.get_marks (27.5, 33.0);
student1.getscore (6.0);
student1.display ();
Output:
Roll No: 1234
return 0; Marks obtained:
Part1 = 27.5
} Part2 = 33
Sports wt: 6
• The child ahs two direct base classes ‘parent 1’ and ‘parent 2’ which
themselves have a common base class ‘grandparent’.
• The child inherits the traits of ‘grandparent’ via two separate paths.
• It can also inherit directly as shown by the broken line. The ‘grandparent’
is sometimes referred to as indirect base class.
• Inheritance by the ‘child’ here might pose some problems. All the public
and protected members of ‘grandparent’ are inherited into the ‘child’
twice, first via ‘parent 1’ and again via ‘parent 2’.
• This means ‘child’ would have duplicate sets of the members inherited
from ‘grandparent’. This introduces ambiguity and should be avoided.
• A solution to this can be provided by making the common base class as
virtual base class while declaring the direct or intermediate base classes.
• When a class is made a virtual base class, C++ takes necessary care to see
that only one copy of that class is inherited, regardless of how many
inheritance paths exist between the virtual class and a derived class.
#include<iostream>
Using namespace std;
class student
{
protected:
int roll_number;
public:
void get_number(int a)
{
roll_number = a;
}
void put_number (void)
{
cout << “Roll No: ” << roll_number<<“\n”;
}
};
class test : virtual public student
{
protected:
float part1, part2;
public:
void get_marks(float x, float y)
{
part1 = x; part2 = y;
}
void put_marks (void)
{
cout << “Marks obtained: ” << “\n”
<< “Part1 = ” << part1 <<“\n”
<< “Part2 = ” << part2 <<“\n”
}
};
class sports: public virtual student
{
protected:
float score;
public:
void get_score(float s)
{
score = s;
}
void put_score (void)
{
cout << “Sports wt: ” << score << “\n\n”;
}
};
class result : public test, public sports
{
protected:
float total;
public:
void display (void);
};
void result :: display (void)
{
total = part1 + part2 + score;
put_number ();
put_marks ();
put score ();
cout << “Total Score: ” << total << “\n”;
}
int main ()
{
result student1;
student1.get_number (678);
student1.get_marks (30.5, 25.5);
student1.getscore (7.0);
student1.display ();
Output:
Roll No: 678
return 0; Marks obtained:
Part1 = 30.5
} Part2 = 25.5
Sports wt: 7
Total Score: 63
Abstract Classes