2. Types of Inheritance and Method Overriding
2.1 Single Inheritance
Definition: One derived class inherits from one base class.
#include <iostream>
#include <string>
using namespace std;
class Person {
protected:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {}
void introduce() {
cout << "Hi, I'm " << name << ", " << age << " years old." << endl;
}
};
class Student : public Person {
private:
string studentId;
double gpa;
public:
Student(string n, int a, string id, double g)
: Person(n, a), studentId(id), gpa(g) {}
void study() {
cout << name << " is studying..." << endl;
}
void showGPA() {
cout << "GPA: " << gpa << endl;
}
};
int main() {
Student s("Alice", 20, "S001", 3.8);
s.introduce(); // Inherited
s.study(); // Own method
s.showGPA(); // Own method
return 0;
}
2.2 Multilevel Inheritance
Definition: A class is derived from another derived class.
#include <iostream>
#include <string>
using namespace std;
// Level 1: Base class
class LivingBeing {
protected:
bool isAlive;
public:
LivingBeing() : isAlive(true) {
cout << "LivingBeing created" << endl;
}
void breathe() {
cout << "Breathing..." << endl;
}
};
// Level 2: Derived from LivingBeing
class Animal : public LivingBeing {
protected:
string species;
public:
Animal(string s) : species(s) {
cout << "Animal created: " << species << endl;
}
void move() {
cout << species << " is moving..." << endl;
}
};
// Level 3: Derived from Animal
class Dog : public Animal {
private:
string name;
public:
Dog(string n) : Animal("Canine"), name(n) {
cout << "Dog created: " << name << endl;
}
void bark() {
cout << name << " is barking!" << endl;
}
void showCapabilities() {
breathe(); // From LivingBeing
move(); // From Animal
bark(); // From Dog
}
};
int main() {
Dog myDog("Buddy");
cout << "\nDog capabilities:" << endl;
myDog.showCapabilities();
return 0;
}
Output:
LivingBeing created
Animal created: Canine
Dog created: Buddy
Dog capabilities:
Breathing...
Canine is moving...
Buddy is barking!
2.3 Multiple Inheritance
Definition: A class inherits from multiple base classes.
#include <iostream>
#include <string>
using namespace std;
class Engine {
protected:
int horsepower;
public:
Engine(int hp) : horsepower(hp) {
cout << "Engine: " << horsepower << " HP" << endl;
}
void start() {
cout << "Engine started: " << horsepower << " HP" << endl;
}
};
class GPS {
protected:
string currentLocation;
public:
GPS(string loc) : currentLocation(loc) {
cout << "GPS initialized at: " << loc << endl;
}
void navigate(string destination) {
cout << "Navigating from " << currentLocation
<< " to " << destination << endl;
}
};
class SmartCar : public Engine, public GPS {
private:
string model;
public:
SmartCar(string m, int hp, string loc)
: Engine(hp), GPS(loc), model(m) {
cout << "SmartCar created: " << model << endl;
}
void drive(string destination) {
cout << "\n=== Driving " << model << " ===" << endl;
start(); // From Engine
navigate(destination); // From GPS
cout << "Arrived at destination!" << endl;
}
};
int main() {
SmartCar tesla("Tesla Model S", 670, "New York");
tesla.drive("Boston");
return 0;
}
Output:
Engine: 670 HP
GPS initialized at: New York
SmartCar created: Tesla Model S
=== Driving Tesla Model S ===
Engine started: 670 HP
Navigating from New York to Boston
Arrived at destination!
Diamond Problem in Multiple Inheritance:
#include <iostream>
using namespace std;
class Device {
protected:
int powerConsumption;
public:
Device(int power) : powerConsumption(power) {
cout << "Device: " << power << "W" << endl;
}
};
// Problem: Both inherit from Device
class Printer : public Device {
public:
Printer(int power) : Device(power) {}
};
class Scanner : public Device {
public:
Scanner(int power) : Device(power) {}
};
// This creates two copies of Device!
class AllInOne : public Printer, public Scanner {
public:
AllInOne(int pPower, int sPower)
: Printer(pPower), Scanner(sPower) {}
// Now we have ambiguity!
};
// Solution: Virtual Inheritance
class DeviceVirtual {
protected:
int powerConsumption;
public:
DeviceVirtual(int power) : powerConsumption(power) {
cout << "Device: " << power << "W" << endl;
}
};
class PrinterVirtual : virtual public DeviceVirtual {
public:
PrinterVirtual(int power) : DeviceVirtual(power) {}
};
class ScannerVirtual : virtual public DeviceVirtual {
public:
ScannerVirtual(int power) : DeviceVirtual(power) {}
};
class AllInOneVirtual : public PrinterVirtual, public ScannerVirtual {
public:
AllInOneVirtual(int power)
: DeviceVirtual(power), PrinterVirtual(power), ScannerVirtual(power) {}
// Now only ONE copy of DeviceVirtual
};
int main() {
AllInOneVirtual device(50);
return 0;
}
2.4 Hierarchical Inheritance
Definition: Multiple derived classes inherit from a single base class.
#include <iostream>
#include <string>
using namespace std;
class Shape {
protected:
string color;
public:
Shape(string c) : color(c) {}
void displayColor() {
cout << "Color: " << color << endl;
}
virtual double getArea() = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(string c, double r) : Shape(c), radius(r) {}
double getArea() override {
return 3.14159 * radius * radius;
}
void display() {
cout << "Circle - ";
displayColor();
cout << "Radius: " << radius << endl;
cout << "Area: " << getArea() << endl;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(string c, double w, double h)
: Shape(c), width(w), height(h) {}
double getArea() override {
return width * height;
}
void display() {
cout << "Rectangle - ";
displayColor();
cout << "Width: " << width << ", Height: " << height << endl;
cout << "Area: " << getArea() << endl;
}
};
class Triangle : public Shape {
private:
double base, height;
public:
Triangle(string c, double b, double h)
: Shape(c), base(b), height(h) {}
double getArea() override {
return 0.5 * base * height;
}
void display() {
cout << "Triangle - ";
displayColor();
cout << "Base: " << base << ", Height: " << height << endl;
cout << "Area: " << getArea() << endl;
}
};
int main() {
Circle circle("Red", 5.0);
Rectangle rect("Blue", 4.0, 6.0);
Triangle tri("Green", 8.0, 5.0);
circle.display();
cout << endl;
rect.display();
cout << endl;
tri.display();
return 0;
}
2.5 Method Overriding
Definition: Redefining a base class method in a derived class.
#include <iostream>
#include <string>
using namespace std;
class Account {
protected:
string accountNumber;
double balance;
public:
Account(string acc, double bal)
: accountNumber(acc), balance(bal) {}
// Method to be overridden
virtual void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
cout << "Withdrawn: $" << amount << endl;
} else {
cout << "Insufficient funds!" << endl;
}
}
virtual void displayInfo() {
cout << "Account: " << accountNumber << endl;
cout << "Balance: $" << balance << endl;
}
double getBalance() { return balance; }
};
class SavingsAccount : public Account {
private:
double minimumBalance;
public:
SavingsAccount(string acc, double bal, double minBal)
: Account(acc, bal), minimumBalance(minBal) {}
// Override withdraw with additional constraint
void withdraw(double amount) override {
if (balance - amount >= minimumBalance) {
balance -= amount;
cout << "Withdrawn: $" << amount << endl;
} else {
cout << "Cannot withdraw: Minimum balance requirement!" << endl;
cout << "Minimum balance: $" << minimumBalance << endl;
}
}
void displayInfo() override {
Account::displayInfo(); // Call base class method
cout << "Minimum Balance: $" << minimumBalance << endl;
cout << "Account Type: Savings" << endl;
}
};
class CheckingAccount : public Account {
private:
double overdraftLimit;
public:
CheckingAccount(string acc, double bal, double overdraft)
: Account(acc, bal), overdraftLimit(overdraft) {}
// Override withdraw with overdraft feature
void withdraw(double amount) override {
if (balance + overdraftLimit >= amount) {
balance -= amount;
cout << "Withdrawn: $" << amount << endl;
if (balance < 0) {
cout << "Warning: Overdraft used! Balance: $" << balance << endl;
}
} else {
cout << "Cannot withdraw: Exceeds overdraft limit!" << endl;
}
}
void displayInfo() override {
Account::displayInfo();
cout << "Overdraft Limit: $" << overdraftLimit << endl;
cout << "Account Type: Checking" << endl;
}
};
int main() {
SavingsAccount savings("SA001", 5000, 1000);
CheckingAccount checking("CA001", 2000, 500);
cout << "=== Savings Account ===" << endl;
savings.displayInfo();
cout << "\nTrying to withdraw $4500..." << endl;
savings.withdraw(4500); // Should fail (below minimum)
cout << "\nTrying to withdraw $3000..." << endl;
savings.withdraw(3000); // Should succeed
cout << "\n=== Checking Account ===" << endl;
checking.displayInfo();
cout << "\nTrying to withdraw $2300..." << endl;
checking.withdraw(2300); // Should succeed with overdraft
return 0;
}
No comments to display
No comments to display