OOP theory
OOP theory
Inheritance (Continued)
Let's continue exploring the different types of inheritance in C++:
3. Multilevel Inheritance
Definition: In multilevel inheritance, a derived class inherits from a base class, and then
another derived class inherits from that first derived class. This forms a chain of
inheritance.
"Is-a" Relationship (Transitive): Multilevel inheritance represents a transitive "is-a"
relationship. If class C inherits from class B, and class B inherits from class A, then class C
is a B, and since B is an A, class C is also an A.
Example (C++):
C++
#include <iostream>
#include <string>
Animal(std::string n) : name(n) {
std::cout << "Animal constructed: " << name << std::endl;
}
void eat() {
std::cout << "Animal is eating." << std::endl;
}
~Animal() {
std::cout << "Animal destructed: " << name << std::endl;
}
};
void breathe() {
std::cout << "Mammal is breathing." << std::endl;
}
~Mammal() {
std::cout << "Mammal destructed: " << name << std::endl;
}
};
void bark() {
std::cout << "Dog is barking." << std::endl;
}
~Dog() {
std::cout << "Dog destructed: " << name << std::endl;
}
};
int main() {
Dog myDog("Buddy");
myDog.eat(); // Inherited from Animal
myDog.breathe(); // Inherited from Mammal
myDog.bark(); // Specific to Dog
return 0;
}
In this example:
4. Hierarchical Inheritance
Definition: In hierarchical inheritance, multiple derived classes inherit from a single base
class. This forms a tree-like structure or hierarchy.
"Is-a" Relationship (Multiple Specializations): Hierarchical inheritance represents
different specializations or types of the base class. For example, Cat is an Animal, and
Dog is an Animal.
Example (C++):
C++
#include <iostream>
#include <string>
std::string name;
virtual ~Shape() {
std::cout << "Shape destructed: " << name << std::endl;
}
};
double width;
double height;
~Rectangle() {
std::cout << "Rectangle destructed." << std::endl;
}
};
double radius;
~Circle() {
std::cout << "Circle destructed." << std::endl;
}
};
int main() {
Rectangle rect(5, 10);
rect.display();
std::cout << "Area of rectangle: " << rect.area() << std::endl;
Circle circ(7);
circ.display();
std::cout << "Area of circle: " << circ.area() << std::endl;
return 0;
}
In this example:
5. Hybrid Inheritance
Definition: Hybrid inheritance is a combination of two or more different types of
inheritance. For example, it can involve a combination of hierarchical and multiple
inheritance.
Complexity: Hybrid inheritance can lead to complex class hierarchies and potential
ambiguities (like the diamond problem) that need to be carefully managed using virtual
inheritance where necessary.
C++
#include <iostream>
int main() {
D obj;
obj.funcA(); // Ambiguous without virtual inheritance in B and C
obj.funcB();
obj.funcC();
obj.funcD();
return 0;
}
In this conceptual example, D inherits from both B and C, which in turn inherit from A. This
creates a hybrid structure. Without virtual inheritance for A in B and C, calling obj.funcA()
would be ambiguous.
C++
#include <iostream>
class A { public: virtual void funcA() { std::cout << "Func A from A\n"; } };
class B : virtual public A { public: void funcB() { std::cout << "Func B\n";
} void funcA() override { std::cout << "Func A from B\n"; } };
class C : virtual public A { public: void funcC() { std::cout << "Func C\n";
} void funcA() override { std::cout << "Func A from C\n"; } };
class D : public B, public C { public: void funcD() { std::cout << "Func
D\n"; } void funcA() override { std::cout << "Func A from D\n"; } };
int main() {
D obj;
obj.funcA(); // Now calls D's funcA due to virtual inheritance and
overriding
obj.funcB();
obj.funcC();
obj.funcD();
return 0;
}
Output:
Func A from D
Func B
Func C
Func D
6. Cyclic Inheritance
Definition: Cyclic inheritance occurs when a class directly or indirectly inherits from
itself. This creates a circular dependency in the inheritance hierarchy.
Not Allowed (Generally): Most programming languages, including C++, do not allow
direct cyclic inheritance because it leads to infinite recursion in class definitions and
object creation, making the size and structure of the objects undefined and causing
compilation errors.
C++
// Direct Cyclic Inheritance (Compiler Error)
// class A : public A {};
int main() {
// B objB; // Will not compile
// C objC; // Will not compile
return 0;
}
The C++ compiler will detect such cyclic dependencies and issue an error, preventing the
program from compiling. Inheritance should always form a directed acyclic graph (DAG) to
maintain a well-defined class hierarchy.