Inheritance
OOP (C++)
Irshad Khan
Objectives
In this chapter, you will learn:
To be able to create new classes by inheriting from existing
classes.
To understand how inheritance promotes software
reusability.
To understand the notions of base classes and derived
classes.
Introduction
Inheritance
New classes created from existing classes
Absorb attributes and behaviors.
Polymorphism
Write programs in a general fashion
Handle a wide variety of existing (and
unspecified) related classes
Introduction
Inheritance:
The mechanism by which one class can inherit the properties of another.
It allows a hierarchy of classes to be built, moving from the most general
to the most specific.
Introduction
Inheritance
Single Inheritance
Class inherits from one base class
Multiple Inheritance
Class inherits from multiple base classes
Three types of inheritance:
public: Derived objects are accessible by the base class
objects (focus of this chapter)
private: Derived objects are inaccessible by the base
class
protected: Derived classes and friends can access
protected members of the base class
Base and Derived Classes
Often an object from a derived class (subclass) “is
an” object of a base class (superclass)
Base class Derived classes
Student GraduateStudent
UndergraduateStudent
Shape Circle
Triangle
Rectangle
Loan CarLoan
HomeImprovementLoan
MortgageLoan
Employee FacultyMember
StaffMember
Account CheckingAccount
SavingsAccount
Fig. Some simple inheritance examples.
Base and Derived Classes
Base and Derived Classes
Base and Derived Classes
Implementation of public inheritance
class CommissionWorker : public Employee {
...
};
Class CommissionWorker inherits from class Employee
friend functions not inherited
private members of base class not accessible from
derived class
Protected Members
protected inheritance
Intermediate level of protection between public and
private inheritance
Derived-class members can refer to public and
protected members of the base class simply by using
the member names
Composition vs. Inheritance
"is a" relationship
Inheritance
"has a" relationship
Composition - class has an object from another class
as a data member
Employee “is a” BirthDate; //Wrong!
Employee “has a” BirthDate;//Composition
Base Class, Derived Class
Base Class
Defines all qualities common to any derived classes.
Derived Class
Inherits those general properties and adds new properties that are specific to that
class.
Example: Base Class
class base {
int x;
public:
void setx(int n) { x = n; }
void showx() { cout << x << ‘\n’ }
};
Example: Derived Class
// Inherit as public
class derived : public base {
int y;
public:
void sety(int n) { y = n; }
void showy() { cout << y << ‘\n’;}
};
Access Specifier: public
The keyword public tells the compiler that base will be inherited such that:
all public members of the base class will
also be public members of derived.
However, all private elements of base will remain private to it and are not
directly accessible by derived.
Example: main()
int main() {
derived ob;
ob.setx(10);
ob.sety(20);
ob.showx();
ob.showy();
}
An incorrect example
class derived : public base {
int y;
public:
void sety(int n) { y = n; }
/* Error ! Cannot access x, which is
private member of base. */
void show_sum() {cout << x+y; }
};
Access Specifier: private
If the access specifier is private :
publicmembers of base become private
members of derived.
these members are still accessible by
member functions of derived.
Example: Derived Class
// Inherit as private
class derived : private base {
int y;
public:
void sety(int n) { y = n; }
void showy() { cout << y << ‘\n’;}
};
Example: main()
int main() {
derived ob;
ob.setx(10); // Error! setx() is private.
ob.sety(20); // OK!
ob.showx(); // Error! showx() is private.
ob.showy(); // OK!
}
Example: Derived Class
class derived : private base {
int y;
public:
// setx is accessible from within derived
void setxy(int n, int m) { setx(n); y = m; }
// showx is also accessible
void showxy() { showx(); cout<<y<< ‘\n’;}
};
Protected Members
Sometimes you want to do the following:
keep a member of a base class private
allow a derived class access to it
Use protected members!
If no derived class, protected members
is the same as private members.
Protected Members
The full general form of a class declaration:
class class-name {
// private members
protected:
// protected members
public:
// public members
};
3 Types of Access Specifiers
Type 1: inherit as private
Base Derived
private members inaccessible
protected members private members
public members private members
3 Types of Access Specifiers
Type 2: inherit as protected
Base Derived
private members inaccessible
protected members protected members
public members protected members
3 Types of Access Specifiers
Type 3: inherit as public
Base Derived
private members inaccessible
protected members protected members
public members public members
Constructor and Destructor
It is possible for both the base class and the derived class to have constructor
and/or destructor functions.
The constructor functions are executed in order of derivation.
i.e.the base class constructor is executed first.
The destructor functions are executed in reverse order.
Passing arguments
What if the constructor functions of both the base class and derived class
take arguments?
1. Pass all necessary arguments to the derived class’s constructor.
2. Then pass the appropriate arguments along to the base class.
Example: Constructor of base
class base {
int i;
public:
base(int n) {
cout << “constructing base \n”;
i = n; }
~base() { cout << “destructing base \n”; }
};
Example: Constructor of derived
class derived : public base {
int j;
public:
derived (int n, int m) : base (m) {
cout << “constructing derived\n”;
j = n; }
~derived() { cout << “destructing derived\n”;}
};
Example: main()
int main() {
derived o(10,20);
return 0;
}
constructing base
constructing derived
destructing derived
destructing base
Multiple Inheritance
Type 1:
base
1
derived
1
derived
2
Multiple Inheritance
• Type 2:
base base
1 2
derived
Example: Type 2
// Create first base class
class B1 {
int a;
public:
B1(int x) { a = x; }
int geta() { return a; }
};
Example: Type 2
// Create second base class
class B2 {
int b;
public:
B2(int x) { b = x; }
int getb() { return b; }
};
Example: Type 2
// Directly inherit two base classes.
class D : public B1, public B2 {
int c;
public:
D(int x, int y, int z) : B1(z), B2(y) {
c = x; }
void show() {
cout << geta() << getb() << c;}
};
Potential Problem
Base Base
Derived Derived
1 2
Derived
3
Base is inherited twice by Derived 3!
Virtual Base Class
To resolve this problem, virtual base class can be used.
class base {
public:
int i;
};
Virtual Base Class
// Inherit base as virtual
class D1 : virtual public base {
public:
int j;
};
class D2 : virtual public base {
public:
int k;
};
Virtual Base Class
/* Here, D3 inherits both D1 and D2.
However, only one copy of base is present */
class D3 : public D1, public D2 {
public:
int product () { return i * j * k; }
};
Casting Base Class Pointers to Derived Class
Pointers
Object of a derived class
Can be treated as an object of the base class
Reverse not true - base class objects not a derived-
class object
Downcasting a pointer
Use an explicit cast to convert a base-class pointer to
a derived-class pointer
Be sure that the type of the pointer matches the type
of object to which the pointer points
derivedPtr = static_cast< DerivedClass * > basePtr;
Pointers to Derived Classes
A pointer declared as a pointer to base class can also be used to point to any
class derived from that base.
However, only those members of the derived object that were inherited from
the base can be accessed.
Example
base *p; // base class pointer
base B_obj;
derived D_obj;
p = &B_obj; // p can point to base object
p = &D_obj; // p can also point to derived // object
Virtual Function
A virtual function is a member function
declared within a base class
redefined by a derived class (i.e. overriding)
It can be used to support run-time polymorphism.
Example
class base {
public:
int i;
base (int x) { i = x; }
virtual void func() {cout << i; }
};
Example
class derived : public base {
public:
derived (int x) : base (x) {}
// The keyword virtual is not needed.
void func() {cout << i * i; }
};
Example
int main() {
base ob(10), *p;
derived d_ob(10);
p = &ob;
p->func(); // use base’s func()
p = &d_ob;
p->func(); // use derived’s func()
}
Pure Virtual Functions
A pure virtual function has no definition relative to the base class.
Only the function’s prototype is included.
General form:
virtual type func-name(paremeter-list) = 0
Abstract Base Classes
Abstract Base classes have virtual function without definition (Pure Virtual
Functions)
Cannot be used to instantiate objects.
But an abstract class is not totally useless. It can be used to create pointers to
it, and take advantage of all its polymorphic abilities.
Example: area
class area {
public:
double dim1, dim2;
area(double x, double y)
{dim1 = x; dim2 = y;}
// pure virtual function
virtual double getarea() = 0;
};
Example: rectangle
class rectangle : public area {
public:
// function overriding
double getarea() {
return dim1 * dim2;
}
};
Example: triangle
class triangle : public area {
public:
// function overriding
double getarea() {
return 0.5 * dim1 * dim2;
}
};
Software Engineering With Inheritance
Classes are often closely related
“Factor out” common attributes and behaviors and
place these in a base class
Use inheritance to form derived classes
Modifications to a base class
Derived classes do not change as long as the public
and protected interfaces are the same
Derived classes may need to be recompiled
????