Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that allows a class (called a derived class) to inherit properties and behaviors (methods) from another class (called a base class). This promotes code reusability and establishes a natural hierarchy between classes.

Key Concepts

  1. Base Class (Parent Class): The class whose properties and methods are inherited.
  2. Derived Class (Child Class): The class that inherits from the base class.
  3. Access Specifiers: Control the access level of the base class members in the derived class (public, protected, private).
  4. Constructor and Destructor: Special functions that are called when an object is created or destroyed. Inheritance affects their behavior.

Syntax

class BaseClass {
public:
    // Base class members
};

class DerivedClass : public BaseClass {
public:
    // Derived class members
};

Example

Let's look at a practical example to understand inheritance better.

Base Class: Animal

#include <iostream>
using namespace std;

class Animal {
public:
    void eat() {
        cout << "This animal eats food." << endl;
    }
};

Derived Class: Dog

class Dog : public Animal {
public:
    void bark() {
        cout << "The dog barks." << endl;
    }
};

int main() {
    Dog myDog;
    myDog.eat();  // Inherited from Animal
    myDog.bark(); // Defined in Dog
    return 0;
}

Explanation

  • Animal Class: Contains a method eat().
  • Dog Class: Inherits from Animal and adds a new method bark().
  • Main Function: Creates an object of Dog and calls both eat() and bark() methods.

Access Specifiers

Access specifiers determine how the members of the base class are accessed in the derived class.

Access Specifier Public Members Protected Members Private Members
public Inherited as public Inherited as protected Not inherited
protected Inherited as protected Inherited as protected Not inherited
private Inherited as private Inherited as private Not inherited

Example with Access Specifiers

class Base {
protected:
    int protectedVar;
public:
    int publicVar;
};

class Derived : public Base {
public:
    void display() {
        cout << "Protected Variable: " << protectedVar << endl;
        cout << "Public Variable: " << publicVar << endl;
    }
};

int main() {
    Derived obj;
    obj.publicVar = 10;
    // obj.protectedVar = 20; // Error: protectedVar is not accessible directly
    obj.display();
    return 0;
}

Constructor and Destructor in Inheritance

When a derived class object is created, the base class constructor is called first, followed by the derived class constructor. Similarly, when the object is destroyed, the derived class destructor is called first, followed by the base class destructor.

Example

class Base {
public:
    Base() {
        cout << "Base class constructor called." << endl;
    }
    ~Base() {
        cout << "Base class destructor called." << endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        cout << "Derived class constructor called." << endl;
    }
    ~Derived() {
        cout << "Derived class destructor called." << endl;
    }
};

int main() {
    Derived obj;
    return 0;
}

Output

Base class constructor called.
Derived class constructor called.
Derived class destructor called.
Base class destructor called.

Practical Exercises

Exercise 1: Basic Inheritance

Task: Create a base class Vehicle with a method move(). Create a derived class Car that inherits from Vehicle and adds a method honk().

Solution:

#include <iostream>
using namespace std;

class Vehicle {
public:
    void move() {
        cout << "The vehicle is moving." << endl;
    }
};

class Car : public Vehicle {
public:
    void honk() {
        cout << "The car is honking." << endl;
    }
};

int main() {
    Car myCar;
    myCar.move(); // Inherited from Vehicle
    myCar.honk(); // Defined in Car
    return 0;
}

Exercise 2: Access Specifiers

Task: Modify the Vehicle class to have a protected member speed and a public method setSpeed(int). In the Car class, add a method displaySpeed() to print the speed.

Solution:

#include <iostream>
using namespace std;

class Vehicle {
protected:
    int speed;
public:
    void setSpeed(int s) {
        speed = s;
    }
};

class Car : public Vehicle {
public:
    void displaySpeed() {
        cout << "The car speed is: " << speed << " km/h" << endl;
    }
};

int main() {
    Car myCar;
    myCar.setSpeed(120);
    myCar.displaySpeed();
    return 0;
}

Common Mistakes and Tips

  • Accessing Private Members: Remember that private members of the base class are not accessible in the derived class.
  • Constructor Initialization: Always ensure that the base class constructor is properly called when initializing derived class objects.
  • Overriding Methods: Be cautious when overriding methods in the derived class. Use the virtual keyword in the base class to allow proper overriding.

Conclusion

Inheritance is a powerful feature in C++ that promotes code reusability and establishes a clear hierarchy between classes. By understanding and utilizing inheritance, you can create more organized and maintainable code. In the next section, we will delve into polymorphism, which builds upon the concepts of inheritance to allow for more dynamic and flexible code behavior.

© Copyright 2024. All rights reserved