Skip to main content

1. Basic Concepts of Inheritance

1.1 What is Inheritance?

Inheritance is a mechanism where a class (derived/child class) can inherit properties and methods from another class (base/parent class).

Real-World Analogy: Think of inheritance like family traits:

  • A child inherits characteristics from parents (eye color, height)
  • The child can also have unique characteristics
  • The child can modify inherited traits (different hairstyle)

Benefits of Inheritance:

  • Code Reusability: Write once, use in multiple classes
  • Logical Hierarchy: Represents real-world relationships
  • Easier Maintenance: Changes in base class automatically reflect in derived classes
  • Polymorphism: Enables treating derived objects as base objects

1.2 Basic Syntax

// Base class (Parent)
class BaseClass {
    // members
};

// Derived class (Child)
class DerivedClass : access_specifier BaseClass {
    // additional members
};

Example:

#include <iostream>
#include <string>
using namespace std;

// Base class
class Animal {
protected:
    string name;
    int age;
    
public:
    Animal(string n, int a) : name(n), age(a) {
        cout << "Animal constructor called" << endl;
    }
    
    void eat() {
        cout << name << " is eating..." << endl;
    }
    
    void sleep() {
        cout << name << " is sleeping..." << endl;
    }
    
    void displayInfo() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

// Derived class
class Dog : public Animal {
private:
    string breed;
    
public:
    Dog(string n, int a, string b) : Animal(n, a), breed(b) {
        cout << "Dog constructor called" << endl;
    }
    
    void bark() {
        cout << name << " is barking: Woof! Woof!" << endl;
    }
    
    void displayDogInfo() {
        displayInfo();  // Inherited method
        cout << "Breed: " << breed << endl;
    }
};

int main() {
    Dog myDog("Buddy", 3, "Golden Retriever");
    
    // Using inherited methods
    myDog.eat();
    myDog.sleep();
    
    // Using derived class method
    myDog.bark();
    
    myDog.displayDogInfo();
    
    return 0;
}

Output:

Animal constructor called
Dog constructor called
Buddy is eating...
Buddy is sleeping...
Buddy is barking: Woof! Woof!
Name: Buddy, Age: 3
Breed: Golden Retriever

1.3 Access Specifiers in Inheritance

Three Types of Inheritance:

Base Class Member public Inheritance protected Inheritance private Inheritance
public members public protected private
protected members protected protected private
private members Not accessible Not accessible Not accessible

Example:

#include <iostream>
using namespace std;

class Base {
private:
    int privateVar;
    
protected:
    int protectedVar;
    
public:
    int publicVar;
    
    Base() : privateVar(1), protectedVar(2), publicVar(3) {}
};

// Public Inheritance
class PublicDerived : public Base {
public:
    void access() {
        // privateVar = 10;     // ERROR: private not accessible
        protectedVar = 20;      // OK: protected -> protected
        publicVar = 30;         // OK: public -> public
    }
};

// Protected Inheritance
class ProtectedDerived : protected Base {
public:
    void access() {
        // privateVar = 10;     // ERROR: private not accessible
        protectedVar = 20;      // OK: protected -> protected
        publicVar = 30;         // OK: public -> protected
    }
};

// Private Inheritance
class PrivateDerived : private Base {
public:
    void access() {
        // privateVar = 10;     // ERROR: private not accessible
        protectedVar = 20;      // OK: protected -> private
        publicVar = 30;         // OK: public -> private
    }
};

int main() {
    PublicDerived pub;
    pub.publicVar = 100;        // OK: public member accessible
    // pub.protectedVar = 200;  // ERROR: protected not accessible outside
    
    ProtectedDerived prot;
    // prot.publicVar = 100;    // ERROR: public became protected
    
    PrivateDerived priv;
    // priv.publicVar = 100;    // ERROR: public became private
    
    return 0;
}

Best Practice: Use public inheritance for most cases (is-a relationship).

1.4 Constructor and Destructor in Inheritance

Execution Order:

  1. Construction: Base class constructor → Derived class constructor
  2. Destruction: Derived class destructor → Base class destructor
#include <iostream>
#include <string>
using namespace std;

class Vehicle {
protected:
    string brand;
    
public:
    Vehicle(string b) : brand(b) {
        cout << "Vehicle constructor: " << brand << endl;
    }
    
    ~Vehicle() {
        cout << "Vehicle destructor: " << brand << endl;
    }
};

class Car : public Vehicle {
private:
    string model;
    
public:
    Car(string b, string m) : Vehicle(b), model(m) {
        cout << "Car constructor: " << model << endl;
    }
    
    ~Car() {
        cout << "Car destructor: " << model << endl;
    }
};

class ElectricCar : public Car {
private:
    int batteryCapacity;
    
public:
    ElectricCar(string b, string m, int battery) 
        : Car(b, m), batteryCapacity(battery) {
        cout << "ElectricCar constructor: " << batteryCapacity << " kWh" << endl;
    }
    
    ~ElectricCar() {
        cout << "ElectricCar destructor: " << batteryCapacity << " kWh" << endl;
    }
};

int main() {
    cout << "=== Creating ElectricCar ===" << endl;
    ElectricCar tesla("Tesla", "Model 3", 75);
    
    cout << "\n=== Destroying ElectricCar ===" << endl;
    // Destructor called automatically when going out of scope
    
    return 0;
}

Output:

=== Creating ElectricCar ===
Vehicle constructor: Tesla
Car constructor: Model 3
ElectricCar constructor: 75 kWh

=== Destroying ElectricCar ===
ElectricCar destructor: 75 kWh
Car destructor: Model 3
Vehicle destructor: Tesla

1.5 Practical Example: Employee Hierarchy

#include <iostream>
#include <string>
using namespace std;

class Employee {
protected:
    string name;
    int id;
    double baseSalary;
    
public:
    Employee(string n, int i, double salary) 
        : name(n), id(i), baseSalary(salary) {}
    
    void displayBasicInfo() {
        cout << "Name: " << name << endl;
        cout << "ID: " << id << endl;
        cout << "Base Salary: $" << baseSalary << endl;
    }
    
    void work() {
        cout << name << " is working..." << endl;
    }
    
    virtual double calculateSalary() {
        return baseSalary;
    }
};

class Manager : public Employee {
private:
    double bonus;
    int teamSize;
    
public:
    Manager(string n, int i, double salary, double b, int team)
        : Employee(n, i, salary), bonus(b), teamSize(team) {}
    
    void displayManagerInfo() {
        displayBasicInfo();
        cout << "Bonus: $" << bonus << endl;
        cout << "Team Size: " << teamSize << endl;
    }
    
    void conductMeeting() {
        cout << name << " is conducting a meeting..." << endl;
    }
    
    double calculateSalary() override {
        return baseSalary + bonus;
    }
};

class Developer : public Employee {
private:
    string programmingLanguage;
    int projectsCompleted;
    
public:
    Developer(string n, int i, double salary, string lang, int projects)
        : Employee(n, i, salary), programmingLanguage(lang), 
          projectsCompleted(projects) {}
    
    void displayDeveloperInfo() {
        displayBasicInfo();
        cout << "Programming Language: " << programmingLanguage << endl;
        cout << "Projects Completed: " << projectsCompleted << endl;
    }
    
    void writeCode() {
        cout << name << " is writing " << programmingLanguage << " code..." << endl;
    }
    
    double calculateSalary() override {
        return baseSalary + (projectsCompleted * 500);
    }
};

int main() {
    Manager mgr("Alice Johnson", 101, 8000, 2000, 10);
    Developer dev("Bob Smith", 102, 6000, "C++", 5);
    
    cout << "=== Manager Information ===" << endl;
    mgr.displayManagerInfo();
    mgr.work();           // Inherited
    mgr.conductMeeting(); // Own method
    cout << "Total Salary: $" << mgr.calculateSalary() << endl;
    
    cout << "\n=== Developer Information ===" << endl;
    dev.displayDeveloperInfo();
    dev.work();           // Inherited
    dev.writeCode();      // Own method
    cout << "Total Salary: $" << dev.calculateSalary() << endl;
    
    return 0;
}