Inheritance in C++

Inheritance is a fundamental concept in C++ and object-oriented programming (OOP) that allows you to create a new class (called a subclass or derived class) based on an existing class (called a superclass or base class). Inheritance enables code reuse and promotes the creation of hierarchical relationships between classes.

Why and when to use inheritance?

Inheritance in C++ is employed when you want to create a new class that is a specialized version of an existing class, allowing you to reuse and extend the functionality of the base class. It is particularly useful when you have a hierarchy of classes with shared attributes and behaviors, as it promotes code reusability, simplifies maintenance, and enables the creation of a more organized and efficient code structure.

Inheritance is typically applied when you need to model "is-a" relationships, such as a derived class representing a specific type of the base class, and it is a fundamental concept in object-oriented programming.

Here's a detailed explanation with examples:

Declaring a Base Class

To create a base class, you define a class with attributes and methods as you normally would.

class Shape { protected: // Access specifier int width; int height; public: void setDimensions(int w, int h) { width = w; height = h; } };

In this example, we have a base class Shape with attributes for width and height and a method to set their values.

Creating a Derived Class

To create a derived class, you specify the base class from which it should inherit using a colon (:) followed by the access specifier (public, private, or protected).

class Rectangle : public Shape { public: int calculateArea() { return width * height; } };

Here, we've created a derived class Rectangle that inherits from the base class Shape. The public specifier means that the public members of Shape are accessible in Rectangle.

Accessing Base Class Members

In the derived class, you can access the attributes and methods of the base class using the dot operator.

Rectangle rect; rect.setDimensions(5, 4); int area = rect.calculateArea(); // Calls the base class method and computes the area.

The derived class Rectangle inherits the setDimensions method from the base class Shape and uses it to set the dimensions. It also adds its own method calculateArea.

Overriding Base Class Methods

You can override (replace) a method from the base class in the derived class by defining a new method with the same name and parameters. This is known as method overriding.

class Square : public Shape { public: int calculateArea() { return width * width; // Override the base class method } };

In this example, the derived class Square overrides the calculateArea method to calculate the area of a square differently than a rectangle.

Types of inheritance in C++

There are three types of inheritance in C++:

Public inheritance

This is the most common type of inheritance. When a class inherits publicly from another class, it inherits all of the public and protected members of the base class.

Protected inheritance

When a class inherits protectedly from another class, it inherits all of the protected and public members of the base class.

Private inheritance

When a class inherits privately from another class, it inherits all of the private and protected members of the base class. However, the derived class's constructors and destructors will not be able to access the base class's private members.

When to use each type of inheritance:
  1. Use public inheritance when you want the derived class to have full access to the base class's members.
  2. Use protected inheritance when you want the derived class to have access to the base class's members, but you also want to restrict access to those members from other classes.
  3. Use private inheritance when you want the derived class to have access to the base class's members, but you also want to hide those members from other classes.

Conclusion

Inheritance allows you to create new classes that inherit properties and behaviors from existing classes. This facilitates code reuse, promotes a hierarchical structure, and is particularly useful when modeling relationships where a derived class "is-a" specialized version of the base class, helping to improve code organization and maintainability.