Inheritance allows one class (called the derived class) to acquire the properties and behaviors (data members and member functions) of another class (called the base class). This promotes code reuse and establishes relationships between classes. C++ supports different types of inheritance to represent various relationship between classes.
Here are the five main types of inheritance in C++:
- Single Inheritance
- Multiple Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
- Hybrid Inheritance
Types of Inheritance
1️⃣ Single Inheritance
In single inheritance, a class inherits from only one base class. This is the simplest form of inheritance and represents a one-to-one relationship between classes. The derived class extends the functionality of a single base class.
Syntax:
class Base {
// Base class members
};
class Derived : public Base {
// Derived class members
};
Example:
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Barking..." << endl;
}
};
int main() {
Dog d;
d.eat(); // Inherited from Animal class
d.bark(); // Defined in Dog class
return 0;
}
In this example:
- The
Dog
class inherits from theAnimal
class. - The
Dog
class can use botheat()
(inherited) andbark()
(defined in Dog).
2️⃣ Multiple Inheritance
In multiple inheritance, a class inherits from more than one base class. This allows the derived class to combine functionalities from multiple base classes, leading to a many-to-one relationship between classes.
Syntax:
class Base1 {
// Base class 1 members
};
class Base2 {
// Base class 2 members
};
class Derived : public Base1, public Base2 {
// Derived class members
};
Example:
#include <iostream>
using namespace std;
class Father {
public:
void height() {
cout << "Father is tall." << endl;
}
};
class Mother {
public:
void skinColor() {
cout << "Mother has fair skin." << endl;
}
};
class Child : public Father, public Mother {
public:
void traits() {
height();
skinColor();
}
};
int main() {
Child c;
c.traits();
return 0;
}
In this example:
- The
Child
class inherits from bothFather
andMother
. - The
Child
class can access members from both base classes.
Considerations:
- Ambiguity: Multiple inheritance can lead to ambiguity when the same member is inherited from more than one base class. This can be resolved using the scope resolution operator or virtual inheritance.
3️⃣ Multilevel Inheritance
In multilevel inheritance, a class is derived from another derived class. This creates a chain of inheritance where a class inherits from a base class, and another class inherits from the derived class. This forms a one-to-one-to-one relationship.
Syntax:
class Base {
// Base class members
};
class Intermediate : public Base {
// Intermediate derived class members
};
class Final : public Intermediate {
// Final derived class members
};
Example:
#include <iostream>
using namespace std;
class LivingBeing {
public:
void breathe() {
cout << "Breathing..." << endl;
}
};
class Animal : public LivingBeing {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Barking..." << endl;
}
};
int main() {
Dog d;
d.breathe(); // Inherited from LivingBeing
d.eat(); // Inherited from Animal
d.bark(); // Defined in Dog
return 0;
}
In this example:
- The
Dog
class inherits fromAnimal
, which in turn inherits fromLivingBeing
. - The
Dog
class inherits members from bothAnimal
andLivingBeing
.
4️⃣ Hierarchical Inheritance
In hierarchical inheritance, multiple classes inherit from the same base class. This creates a one-to-many relationship between the base class and derived classes. Hierarchical inheritance is useful when different derived classes share common properties of a base class but extend it in different ways.
Syntax:
class Base {
// Base class members
};
class Derived1 : public Base {
// Derived class 1 members
};
class Derived2 : public Base {
// Derived class 2 members
};
Example:
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Barking..." << endl;
}
};
class Cat : public Animal {
public:
void meow() {
cout << "Meowing..." << endl;
}
};
int main() {
Dog d;
Cat c;
d.eat(); // Inherited from Animal
d.bark(); // Defined in Dog
c.eat(); // Inherited from Animal
c.meow(); // Defined in Cat
return 0;
}
In this example:
- Both
Dog
andCat
classes inherit from theAnimal
class. - Both classes share the
eat()
method but have their own unique behaviors (bark()
forDog
andmeow()
forCat
).
5️⃣ Hybrid Inheritance
Hybrid inheritance is a combination of two or more types of inheritance (e.g., single, multiple, multilevel, or hierarchical inheritance). Hybrid inheritance can lead to complex relationships, especially when multiple inheritance is involved. It may also involve virtual inheritance to avoid ambiguity when multiple derived classes inherit from the same base class.
Syntax:
class Base {
// Base class members
};
class Derived1 : public Base {
// Derived class 1 members
};
class Derived2 : public Base {
// Derived class 2 members
};
class Final : public Derived1, public Derived2 {
// Final derived class members
};
Example:
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Mammal : public Animal {
public:
void giveBirth() {
cout << "Giving birth..." << endl;
}
};
class Bird : public Animal {
public:
void layEggs() {
cout << "Laying eggs..." << endl;
}
};
class Bat : public Mammal, public Bird {
public:
void fly() {
cout << "Flying..." << endl;
}
};
int main() {
Bat b;
b.eat(); // Ambiguity: resolved using scope resolution or virtual inheritance
b.giveBirth(); // Inherited from Mammal
b.fly(); // Defined in Bat
return 0;
}
In this example:
- The
Bat
class inherits from bothMammal
andBird
, which both inherit fromAnimal
. - Ambiguity arises for the
eat()
method, as it is inherited from bothMammal
andBird
. This can be resolved using virtual inheritance or scope resolution.
Virtual Inheritance
In cases where multiple inheritance leads to ambiguity (such as the diamond problem), virtual inheritance can be used to ensure that only one instance of a base class is inherited, even if multiple derived classes share the same base class.
Diamond Problem:
#include <iostream>
using namespace std;
class Base {
public:
Base() { cout << "Base class constructor" << endl; }
};
class Derived1 : public Base {
public:
Derived1() { cout << "Derived1 class constructor" << endl; }
};
class Derived2 : public Base {
public:
Derived2() { cout << "Derived2 class constructor" << endl; }
};
class Final : public Derived1, public Derived2 {
public:
Final() { cout << "Final class constructor" << endl; }
};
int main() {
Final f;
return 0;
}
Output:
Base class constructor
Derived1 class constructor
Base class constructor
Derived2 class constructor
Final class constructor
Solution:
class Base {
public:
Base() { cout << "Base class constructor" << endl; }
};
class Derived1 : virtual public Base {
public:
Derived1() { cout << "Derived1 class constructor" << endl; }
};
class Derived2 : virtual public Base {
public:
Derived2() { cout << "Derived2 class constructor" << endl; }
};
class Final : public Derived1, public Derived2 {
public:
Final() { cout << "Final class constructor" << endl; }
};
int main() {
Final f;
return 0;
}
Output:
Base class constructor
Derived1 class constructor
Derived2 class constructor
Final class constructor
In this case:
- The
Base
class constructor is called only once, even though bothDerived1
andDerived2
inherit from it. This is achieved using virtual inheritance.