Object-Oriented Programming
Abstract Classes
Pure virtual functions and interface contracts — cannot be instantiated
Interview: OOP design — abstract classes vs interfaces, pure virtual, and how to enforce implementation contracts
Abstract Classes
An abstract class is a class with at least one pure virtual function — declared with = 0. Abstract classes cannot be instantiated directly. They define an interface contract: any concrete derived class must provide implementations for all pure virtual functions, or it too becomes abstract.
Pure Virtual Functions
virtual void draw() = 0; declares a pure virtual function. It has no implementation in the base class (though you can provide one as an optional default that derived classes call explicitly). Derived classes must override it or they remain abstract and cannot be instantiated.
C++ Interfaces
C++ has no interface keyword (unlike Java/C#). The idiom for a pure interface is an abstract class with only pure virtual functions and a virtual destructor, no data members. This achieves the same effect: define the API contract, enforce implementation in concrete classes.
Abstract Classes vs Concrete Classes
Abstract classes model "is-a" relationships at the concept level — they define what a type can do without specifying how. Concrete classes provide the "how". This separation (Open/Closed Principle) allows adding new behaviors by adding derived classes rather than modifying existing ones.
Interview Corner
Q: What is the difference between a pure virtual function and a regular virtual function?
A: A regular virtual function has a default implementation in the base class — derived classes can override it or use the default. A pure virtual function (= 0) requires every non-abstract derived class to provide its own implementation — there is no meaningful default. Pure virtual makes the class abstract and forces the contract.
Q: Can an abstract class have a constructor?
A: Yes. Although abstract classes can't be instantiated directly, their constructors are called when a derived class is constructed (as the base part of the derived object). Abstract class constructors typically initialize common data members. They should be protected to prevent direct instantiation attempts and to signal that the constructor is only for use by derived classes.
Common Pitfalls
- Non-virtual destructor in abstract class: Even abstract classes used as base classes need
virtual ~AbstractBase() = default;to ensure proper deletion through base pointers. - Forgetting to implement all pure virtuals: If a derived class fails to implement a pure virtual, it remains abstract and cannot be instantiated — a compile error.
Best Practices
- Always declare the destructor of abstract/base classes as
virtual ~Base() = default; - Mark concrete final implementations with
overrideand optionallyfinalto communicate intent and get compiler checking. - Use abstract classes to define stable interfaces — clients depend on the abstract type, not the concrete implementation (Dependency Inversion Principle).