Polymorphism: Deriving a Class from an Abstract Class

What is it?

In C++, an abstract class is a class that has at least one pure virtual function. Polymorphism allows us to treat derived classes as their base class type, and when a pure virtual function is called on a base class pointer, the correct derived class function is invoked. Deriving a class from an abstract class and overriding its pure virtual functions is a common use of polymorphism.


Syntax

Here's the syntax of how to derive a class from an abstract class and override the pure virtual function:

class AbstractClass {
public:
    virtual void PureVirtualFunction() = 0;
};

class DerivedClass : public AbstractClass {
public:
    void PureVirtualFunction() override {
        // implementation of the function
    }
};

In this syntax:

  • AbstractClass: This is the name of the abstract class.
  • DerivedClass: This is the name of the derived class.
  • PureVirtualFunction(): This is the pure virtual function declared in the abstract class.



How to use it

To derive a class from an abstract class in C++, follow these steps:

  1. Define an abstract class with at least one pure virtual function.
  2. Define a derived class that inherits from the abstract class.
  3. Override the pure virtual function(s) in the derived class.



Program code snippet example

#include <iostream>

class Animal {
public:
    virtual void makeSound() = 0; // Pure virtual function
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Woof!" << std::endl;
    }
};

int main() {
    Dog myDog;

    Animal* animalPtr = &myDog;

    animalPtr->makeSound(); // Outputs: "Woof!"

    return 0;
}

Output:

Woof!



Important to know

  • An abstract class cannot be instantiated. It is meant to be subclassed, and its pure virtual functions provide a common interface for all its subclasses.
  • In the derived class, you must override all pure virtual functions. If you don't, the derived class will also be considered abstract.
  • Polymorphism works because C++ determines which method to invoke at runtime based on the actual type of the object, not its static type. This is called dynamic binding.



Best practices

When using polymorphism with abstract classes and derived classes, keep the following best practices in mind:

  1. Use meaningful names: This helps make your code more readable and maintainable.

  2. Prefer composition over inheritance when possible: This is a common principle in object-oriented programming. While inheritance (especially from abstract classes) can be powerful, it can also lead to more complex code.

  3. Use virtual destructors when dealing with inheritance: If a class has any virtual functions, it should also have a virtual destructor. This ensures that the correct destructor is called when deleting a base class pointer to a derived object.

  4. Avoid casting if possible: C++ polymorphism should allow you to avoid casting to a specific derived class type in most cases. If you find yourself needing to cast, it may be a sign that your design could be improved.




Create a virtual function, greet(), for the derived class, Boss. It should output "The boss says hello.".