Lesson 10 • Intermediate
Inheritance & Polymorphism
Reuse code through inheritance and write flexible, extensible systems with virtual functions and polymorphism.
What You'll Learn
- ✓ Base and derived classes
- ✓ Virtual functions and override
- ✓ Abstract classes and pure virtual functions
- ✓ Multiple inheritance and interfaces
Inheritance — "Is-A" Relationships
Inheritance lets a class inherit attributes and methods from another class. The parent is called the base class, and the child is the derived class.
Think of it like biology: a Dog is an Animal. Dogs inherit traits common to all animals (eating, sleeping) but also have dog-specific traits (barking, fetching).
class Base { /* shared stuff */ };
class Derived : public Base { /* extra stuff */ };| Access | In Base | In Derived | Outside |
|---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
Inheritance Basics
Build Animal, Dog, and Cat classes with inherited and unique behaviors
#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 created: " << name << endl;
}
void eat() const {
cout << name << " is eating." << endl;
}
void sleep() const {
cout << name << " is sleeping. Zzz..." << endl;
}
void info() const {
cout << name << " (age: " << age << ")" <
...Polymorphism — One Interface, Many Forms
Polymorphism means "many forms." With virtual functions, you can call the same method on different object types and get different behavior — decided at runtime.
class Shape {
virtual double area() const = 0; // Pure virtual (abstract)
virtual void draw() const { } // Virtual (overridable)
};
class Circle : public Shape {
double area() const override { return 3.14 * r * r; }
void draw() const override { cout << "Drawing circle"; }
};Key rule: Use a base class pointer or reference to access derived objects. The virtual keyword ensures the correct derived method is called.
Polymorphism & Abstract Classes
Build a shape hierarchy with virtual functions and runtime dispatch
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Base class with virtual functions
class Shape {
protected:
string name;
string color;
public:
Shape(string n, string c) : name(n), color(c) {}
// Virtual function — CAN be overridden
virtual double area() const {
return 0;
}
// Pure virtual — MUST be overridden (makes class abstract)
virtual void draw() const = 0;
// Virtual destructor — essential for polym
...Multiple Inheritance & Interfaces
Combine Employee with Printable and Serializable interfaces
#include <iostream>
#include <string>
using namespace std;
// Interface-like classes (abstract)
class Printable {
public:
virtual void print() const = 0;
virtual ~Printable() = default;
};
class Serializable {
public:
virtual string serialize() const = 0;
virtual ~Serializable() = default;
};
// Base class
class Employee {
protected:
string name;
double salary;
public:
Employee(string n, double s) : name(n), salary(s) {}
virtual ~Employee() = default;
...Common Mistakes
⚠️ Missing virtual destructor: Without virtual ~Base(), deleting a derived object through a base pointer causes undefined behavior.
⚠️ Forgetting override: Without override, typos in function signatures create new functions instead of overriding.
⚠️ Slicing: Assigning a derived object to a base variable (not pointer/reference) slices off the derived data.
⚠️ Diamond problem: Multiple inheritance from two classes that share a base creates ambiguity. Use virtual inheritance to solve it.
Pro Tips
💡 Always use override: It catches typos at compile time — the compiler verifies you're actually overriding a base method.
💡 Prefer composition over inheritance: "Has-a" relationships (a Car has an Engine) are often better than "is-a" inheritance hierarchies.
💡 Use abstract classes as interfaces: Classes with only pure virtual functions act like Java/C# interfaces.
Lesson Complete!
You can now build class hierarchies with inheritance and write flexible code with polymorphism. Next up: Templates — write generic code that works with any type.
Sign up for free to track which lessons you've completed and get learning reminders.