Module-6
Inheritance
What Is Inheritance?
• Provides a way to create a new class from an
existing class
• The new class is a specialized version of the
existing class
• The process by which objects of one class
acquired the properties of another classes.
CS1 -- Inheritance and Polymorphism 2
Example: Insect Taxonomy
CS1 -- Inheritance and Polymorphism 3
Inheritance – Terminology and
Notation in C++
• Base class (or parent) – inherited from
• Derived class (or child) – inherits from the base class
• Notation:
class Student // base class
{
. . .
};
class UnderGrad : public student
{ // derived class
. . .
};
CS1 -- Inheritance and Polymorphism 4
The "is a" Relationship
• Inheritance establishes an "is a"
relationship between classes.
– A poodle is a dog
– A car is a vehicle
– A flower is a plant
– A football player is an athlete
CS1 -- Inheritance and Polymorphism 5
Types of Inheritances
• Single Inheritance
• Multiple Inheritance
• Multilevel Inheritance
• Hierarchical Inheritance
• Hybrid Inheritance
Single Inheritance
In single inheritance, a class drives from one
base class only. This means that there is only
one subclass that is derived from one
superclass.
Class A Base Class/Parent Class/ Super Class
Class B Derived Class / Child Class / Sub Class
#include<iostream>
using namspace std;
class father
{
public:
void house()
{
cout<<“Have own 3BHK House”<<endl;
}
};
class son:public father
{
public:
void car()
{
cout”Have own Audi car”<<endl;
}
};
int main()
{
son o;
o.house();
o.car;
return o;
}
Multiple Inheritance
• Multiple Inheritance is a type of inheritance in
which a class derives from more than one
classes. As shown in the below diagram, class
C is a sub class that has class A and class B as
its parent.
#include<iostream> class son:public father, public mother
using namspace std; {
class father public:
{ void Coding()
public: {
void Driving() cout”Learn Coding”<<endl;
{ }
cout<<“Learn Driving”<<endl; };
} int main()
}; {
class mother son o;
{ o.Driving();
Void Cooking() o.Cooking();
{ o.Coding();
cout<<“Learn Cooking”<<endl return o;
} }
};
Multilevel Inheritance
• In multilevel inheritance, a class is derived
from another derived class. This inheritance
can have as many levels such as long as our
implementation. In the below diagram, class C
is derived from Class B. Class B is in turn
derived from class A.
#include<iostream> class son:public father
using namspace std; {
class Grandfather public:
{ void Car()
public: {
void Land() cout”Audi Car”<<endl;
{ }
cout<<“5 Acre Land”<<endl; };
} int main()
}; {
class father:public Grandfather son o;
{ o.Land();
Void House() o.House();
{ o.Car();
cout<<“3 BHK hose”<<endl return o;
} }
};
Hybrid Inheritance
Hybrid Inheritance is usually a combination of more than one
type of inheritance
#include<iostream>
using namspace std;
class Grandfather
{
public:
class son:public father, public mother
void Land()
{
{
public:
cout<<“5 Acre Land”<<endl;
void Car()
}
{
};
cout”Audi Car”<<endl;
class father:public Grandfather
}
{
};
Void House()
int main()
{
{
cout<<“3 BHK hose”<<endl
son o;
}
o.Land();
};
o.House();
class mother
o.Gold
{
o.Car();
Void Gold()
return o;
{
}
cout<<“25 Kg of Gold”<<endl
}
};
Hierarchical Inheritance
In Hierarchical Inheritance, more than one class inherits from a single
base class
#include<iostream> void getCircleDetails; int main()
using namspace std; { {
class shape cout<<(“Enter Radius “); rectangle r;
{ cin>>radius; circle c;
public: } square s;
float length,breadth,radius; double circle_area() r.getRectangleDetails();
}; { cout<<“Area of Rectangle :
class rectangle:public shape return 3.14*(radius*radius); “<<r.rectangle_area()<<endl;
{ } c.getCircleDetails();
public: }; cout<<“Area of Circle: ”<<
void getRectangleDetails() class square:public shape c.circle_area()<<endl;
{ { s.getSquareDetails();
cout<<“Enter Length: “; public: cout<<“Area of Square: “
Cin<<length; void getCircleDetails() <<s.square_area()<<endl
Cout<<“Enter Breadth: “; { return 0;
cin<<breadth; cout<<“Enter Length “); }
} cin>>length;
float rectangle_area() }
{ double square_area()
return length*breadth; (
} reurn length*length;
}; }
Class circle:public shape };
{
Public:
What Does a Child Have?
An object of the derived class has:
• all members defined in child class
• all members declared in parent class
An object of the derived class can use:
• all public members defined in child class
• all public members defined in parent
class
CS1 -- Inheritance and Polymorphism 17
Protected Members and
Class Access
• protected member access
specification: like private, but
accessible by objects of derived class
• Class access specification: determines
how private, protected, and
public members of base class are
inherited by the derived class
CS1 -- Inheritance and Polymorphism 18
Class Access Specifiers
1) public – object of base class can be
treated as object of derived class (not vice-
versa)
2) protected – more restrictive than
public, but allows derived classes to know
details of parents
3) private – prevents objects of derived
class from being treated as objects of base
class.
CS1 -- Inheritance and Polymorphism 19
Inheritance vs. Access
How inherited base class
members
Base class members appear in derived class
private: x private x is inaccessible
protected: y base class
private: y
public: z private: z
private: x protected x is inaccessible
protected: y base class protected: y
public: z protected: z
private: x public x is inaccessible
protected: y base class protected: y
public: z public: z
CS1 -- Inheritance and Polymorphism 20
Multipath-Inheritance
Diamond Problem in C++
#include<iostream>
using namspace std; class C:public A
class A {
{ public:
public: void view()
void display() {
{ cot<<“View method in C: “;
cout<<“Display method in A: “; }
} };
}; class D:public B, public C
void get()
Class B:public A {
{ cout<<“”Get Method in D: “;
public: }
void show() };
{ int main()
cout<<“Show method in B: “; {
} D.o;
}; o.display()
#include<iostream>
using namspace std; class C:virtual public A
class A {
{ public:
public: void view()
void display() {
{ cout<<“View method in C: “;
cout<<“Display method in A: “; }
} };
}; class D:public B, public C
void get()
class B:virtual public A {
{ cout<<“”Get Method in D: “;
public: }
void show() };
{ int main()
cout<<“Show method in B: “; {
} D.o;
}; o.display()
return 0;
}
Vehicle Inheritance Hierarchy: Create a hierarchy of vehicle
classes, such as Car, Motorcycle, and Bicycle, derived from
a base class called Vehicle. Implement specific properties
and methods for each derived class, such as the number of
wheels, maximum speed, and fuel efficiency. Demonstrate
inheritance by accessing and modifying the properties and
methods of the derived classes.
Bank Account Inheritance: Implement a bank account
inheritance hierarchy with a base class called Account and
derived classes such as SavingsAccount and
CheckingAccount. Each derived class should have specific
properties and methods, such as an interest rate for savings
accounts and overdraft protection for checking accounts.
Perform operations like deposit, withdrawal, and balance
inquiry on various types of accounts using inheritance.
Shape Inheritance: Design a shape inheritance hierarchy
with a base class called Shape and derived classes like
Rectangle, Circle, and Triangle. Each derived class should
have specific properties and methods, such as calculating
the area and perimeter. Use inheritance to create objects of
different shapes and perform calculations based on their
specific properties.
Employee Inheritance: Create an employee inheritance
hierarchy with a base class called Employee and derived
classes like Manager, Engineer, and Salesperson. Each
derived class should have specific properties, such as a
bonus percentage for managers and sales targets for
salespersons. Implement methods like calculating the
salary and displaying employee details using inheritance.
Animal Inheritance: Construct an animal inheritance
hierarchy with a base class called Animal and derived classes
like Dog, Cat, and Bird. Each derived class should have
specific properties and methods, such as the ability to bark
for dogs, meow for cats, and fly for birds. Utilize inheritance
to create and interact with different types of animals.
These example problems demonstrate the concept of
inheritance in various scenarios, showcasing how it enables
code reuse, extensibility, and polymorphic behavior in object-
oriented programming.
Scenario: Vehicle Hierarchy
You are tasked with creating a vehicle hierarchy in a software system for a
transportation company. The system needs to manage various types of vehicles,
including cars, motorcycles, and bicycles. To implement this, you decide to design a
hierarchy of classes derived from a base class called Vehicle. Each derived class will have
specific properties and methods related to its type.
Base Class: Vehicle
Properties: Number of wheels, maximum speed, fuel efficiency
Methods: Get and set methods for each property
Derived Class: Car
Additional Properties: Number of doors, fuel type (petrol, diesel, electric)
Additional Methods: Calculate fuel consumption, display car details
Derived Class: Motorcycle
Additional Properties: Has sidecar (boolean), type of motorcycle (sport, cruiser, off-
road)
Additional Methods: Check if it has a sidecar, display motorcycle details
Derived Class: Bicycle
Additional Properties: Number of gears, type of bicycle (mountain, road, hybrid)
Additional Methods: Calculate average speed, display bicycle details
#include <iostream>
#include <conio>
using namespace std;
class person
{
public:
char name[100];
int code;
void input()
{
cout<<"\nEnter the name of the person : ";
cin>>name;
cout<<endl<<"Enter the code of the person : ";
cin>>code; }
void display()
{
cout<<endl<<"Name of the person : "<<name;
cout<<endl<<"Code of the person : "<<code;
} };
class account:virtual public person
{
public: float pay;
void getpay()
{
cout<<endl<<"Enter the pay : ";
cin>>pay;
}
void display()
{ cout<<endl<<"Pay : "<<pay;
} };
class admin:virtual public person
{
public: int experience;
void getexp()
{
cout<<endl<<"Enter the experience : ";
cin>>experience;
}
void display()
{
cout<<endl<<"Experience : "<<experience;
} };
class master:public account,public admin
{
public: char n[100];
void gettotal()
{
cout<<endl<<"Enter the company name : ";
cin>>n; } void display() { cout<<endl<<"Company name : "<<n;
} };
int main()
{
master m1;
m1.input();
m1.getpay();
m1.getexp();
m1.gettotal();
m1.person::display();
m1.account::display();
m1.admin::display();
m1.display();
return 0;
}
Inheritance and Constructors
#include<iostream>
using namspace std; class C:public A
class A {
{ public:
public: C()
A() {
{ cout<<“Constructing C “<<endl;
cout<<“Constructing A “<<endl; }
} };
}; class D:public B, public C
class B:public A public:
{ D()
public: {
B() cout<<“”Constructing D “;
{ }
cout<<“Constructing B “<<endl; };
} int main() Output
}; { Constructing A
D o; Constructing B
Return 0; Constructing A
} Constructing C
Constructing D
Inheritance and Constructors
#include<iostream>
using namspace std; class C:public A
class A {
{ public:
public: C()
int X; {
A() cout<<“Constructing C “<<endl;
{ }
cout<<“Constructing A “<<endl; };
} class D:public B, public C
}; Public:
D()
class B:public A {
{ cout<<“”Constructing D “<<endl;
public: }
B() };
{ int main() Output
cout<<“Constructing B “<<endl; { Ambiguous error
} D o;
}; o.X=10;
return 0;
}
Inheritance and Constructors
#include<iostream>
using namspace std; class C:virtual public A
class A {
{ public:
public: C()
A() {
{ cout<<“Constructing C “;
cout<<“Constructing A “; }
} };
}; class D:public B, public C
public:
Class B:virtual public A D()
{ {
public: cout<<“”Constructing D “;
B() }
{ };
cout<<“Constructing B “; int main() Output
} { Constructing A
}; D o; Constructing B
return 0; Constructing C
} Constructing D
Example:Bank Account operation
#include<iostream>
using namspace std; class C:virtual public A
{
class A public:
{ C()
public: {
A() cout<<“Constructing C “;
{ }
cout<<“Constructing A “; };
} class D:public B, public C
}; public:
D()
Class B:virtual public A {
{ cout<<“”Constructing D “;
public: }
B() };
{ int main() Output
cout<<“Constructing B “; { Constructing A
} D o; Constructing B
}; return 0; Constructing C
} Constructing D
#include<iostream> cout<<"\nEnter Account Type :";
using namespace std; cin>>actype;
/* }
Account type void displayDetails()
1. Saving Account {
2. Current Account cout<<"\nEnter Customer Name :"<<name;
Operations: cout<<"\nEnter Account Number
Account Creation :"<<accno;
Deposit cout<<"\nEnter Account Type :"<<actype;
Withdraw }
Balance };
*/ class current_account : public account
class account {
{ private:
private: float balance;
string name; public:
int accno; void c_display()
string actype; {
public: cout<<"\nBalance :"<<balance;
void getAccountDetails() }
{ void c_deposit()
cout<<"\nEnter Customer Name :"; {
cin>>name; float deposit;
cout<<"\nEnter Account Number :"; cout<<"\nEnter amount to Deposit : ";
cin>>accno; cin>>deposit;
{
void c_withdraw()
cout<<"\nBalance : "<<sav_balance;
{
}
float withdraw;
void s_deposit()
cout<<"\n\nBalance:"<<balance;
{
cout<<"\nEnter amount to be withdraw :";
float deposit,interest;
cin>>withdraw;
cout<<"\nEnter amount to Deposit :";
if(balance>5000)
sav_balance=sav_balance+deposit;
{
interest=(sav_balance*2)/100;
balance=balance-withdraw;
sav_balance=sav_balance+interest;
cout<<"\nBalance Amount After
}
Wthdraw:"<<balance;
void s_withdraw()
}
{
else{
float withdraw;
cout<<"\n Insufficient Balance";
cout<<"\n\nBalance:"<<sav_balance;
}
cout<<"\nEnter amount to be withdraw
}
:";
};
cin>>withdraw;
class saving_account:public account
if(sav_balance>1000)
{
{
private:
sav_balance=sav_balance-withdraw;
float sav_balance;
cout<<"\nBalance Amount After
public:
Withdraw:"<<sav_balance;
void s_display()
}
Details"<<endl;
else{
cout<<"5) Exit"<<endl;
cout<<"\n Insufficient Balance";
cout<<"Enter your Choice: ";
}
cin>>choice;
}
switch(choice)
};
{
int main()
case 1:
{
s1.s_deposit();
current_account c1;
break;
saving_account s1;
case 2 :
char type;
s1.s_withdraw();
cout<<"\nEnter S for saving customer and C
break;
for current account customer:";
case 3 :
cin>>type;
s1.s_display();
int choice;
break;
if(type=='s' || type=='S')
case 4 :
{
s1.displayDetails();
s1.getAccountDetails();
s1.s_display();
while(1)
break;
{
case 5:
cout<<"\nChoose your Choice"<<endl;
goto end;
cout<<"1) Deposit"<<endl;
default:
cout<<"2) Withdraw"<<endl;
cout<<"\nEntered choice is
cout<<"3) Display Balance"<<endl;
invalid, \"Try Again\"";
cout<<"4) Display with full
}
} Details"<<endl;
} cout<<"5) Exit"<<endl;
else if(type=='c'||type=='C') cout<<"Enter your Choice: ";
{ cin>>choice;
c1.getAccountDetails(); switch(choice)
while(1) {
{ case 1:
cout<<"\nChoose your Choice"<<endl; c1.c_deposit();
cout<<"1) Deposit"<<endl; break;
cout<<"2) Withdraw"<<endl; case 2 :
cout<<"3) Display Balance"<<endl; c1.c_withdraw();
cout<<"4) Display with full break;
case 3 :
} c1.c_display();
else break;
{ case 4 :
cout<<"\nInvalid Account Selection"; c1.displayDetails();
} c1.c_display();
end: break;
cout<<"\nThank You for Banking with case 5:
us.."; goto end;
return 0; default:
} cout<<"\nEntered choice is
invalid, \"Try Again\"";
else (type=='c'||type=='C')
{
Cout<<“\nInvalid Account Selection”;
}
end;:
Cout<<“\nThank you for Banking with us..”;
Return 0;
}
Protected access specifier
In C++, the protected access specifier is used to
declare class members (variables and functions) that
are accessible within the class itself, as well as by
derived classes. It provides a middle ground between
public and private access specifiers.
When a class member is declared as protected, it can
be accessed within the class itself, just like private
members. However, unlike private members,
protected members can also be accessed by derived
classes.
class Base {
protected:
int protectedVariable;
public:
void setProtectedVariable(int value) {
protectedVariable = value;
}
};
class Derived : public Base {
public:
void modifyBaseProtectedVariable(int value) {
protectedVariable = value; // Accessing protected member from derived class
}
};
int main() {
Derived derivedObj;
derivedObj.setProtectedVariable(10); // Accessing protected member through base
class member function
erivedObj.modifyBaseProtectedVariable(20); // Accessing protected member directly
from derived class
return 0;
}
Protected access specifier
#include<iostream>
using namspace std;
class A
{ int main()
public: {
int X; B o;
}; o.getDetails();
Class B:public A o.display();
{ return 0;
public: }
void getDetails()
{
cout<<“\nEnter the value of X:”; OUTPUT
cin>>X; Enter the value of X : 10
} X : 10
void display()
{
cout<<“X: “<<X;
} };
Protected access specifier
#include<iostream>
using namspace std;
class A
{
private:
int X;
};
Class B:public A int main()
{ {
public: B o;
void getDetails() o.getDetails();
{ o.display();
cout<<“\nEnter the value of X:”; return 0;
cin>>X; }
}
void display() OUTPUT
{ ERROR!
cout<<“X: “<<X; error: 'int A::X' is private within this context
} };
Protected access specifier
#include<iostream>
using namspace std; int main()
class A {
{ B o;
protected: o.getDetails();
int X; o.display();
}; return 0;
Class B:public A }
{
public:
void getDetails() OUTPUT
{ Enter the value of X: 12
cout<<“\nEnter the value of X:”; X:12
cin>>X;
}
void display()
{
cout<<“X: “<<X;
} };
Using protected member functions: If the base class
provides protected member functions that access the
private members, the derived class can call these
functions to indirectly access the private members. The
protected member functions act as a bridge between the
base class's private members and the derived class. By
making the derived class a friend of the base class, you
can also access private members directly within the
derived class.
Protected access specifier
#include<iostream>
using namspace std;
class A
{
protected:
int X;
};
Class B:public A int main()
{ {
public: B o;
void getDetails() o.getDetails();
{ o.display();
cout<<“\nEnter the value of X:”; return 0;
cin>>X; }
}
void display() OUTPUT
{ Enter the value of X: 12
cout<<“X: “<<X; X:12
} };
class Base {
private:
int privateVariable;
protected:
void setPrivateVariable(int value) {
privateVariable = value;
}
public:
// ...
};
class Derived : public Base {
public:
void setBasePrivateVariable(int value) {
setPrivateVariable(value);
}
};
int main() {
Derived derivedObj;
derivedObj.setBasePrivateVariable(10);
return 0;
}
Using friend classes: If the derived class is declared as a
friend of the base class, it can access the private
members directly. This approach grants special access
privileges to the derived class, allowing it to access the
private members of the base class.
class Derived : public Base {
class Base { public:
private: void setBasePrivateVariable(Base& obj, int
int privateVariable; value) {
obj.privateVariable = value;
friend class Derived; }
};
public:
// ... int main() {
}; Base baseObj;
Derived derivedObj;
derivedObj.setBasePrivateVariable(baseObj,
10);
return 0;
}