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
- Base Class (Parent Class): The class whose properties and methods are inherited.
- Derived Class (Child Class): The class that inherits from the base class.
- Access Specifiers: Control the access level of the base class members in the derived class (public, protected, private).
- 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 methodbark()
. - Main Function: Creates an object of
Dog
and calls botheat()
andbark()
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.
C++ Programming Course
Module 1: Introduction to C++
- Introduction to C++
- Setting Up the Development Environment
- Basic Syntax and Structure
- Variables and Data Types
- Input and Output
Module 2: Control Structures
Module 3: Functions
Module 4: Arrays and Strings
Module 5: Pointers and References
- Introduction to Pointers
- Pointer Arithmetic
- Pointers and Arrays
- References
- Dynamic Memory Allocation
Module 6: Object-Oriented Programming
- Introduction to OOP
- Classes and Objects
- Constructors and Destructors
- Inheritance
- Polymorphism
- Encapsulation and Abstraction
Module 7: Advanced Topics
- Templates
- Exception Handling
- File I/O
- Standard Template Library (STL)
- Lambda Expressions
- Multithreading