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: 
 
 Construction : Base class constructor → Derived class constructor 
 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;
}