Public inheritance establishes an "is-a" relationship, meaning the derived class object can be treated as an instance of the base class, but it retains its derived class identity and capabilities. Here’s how public inheritance works in this context:
- Abstract Base Class: When a class has at least one pure virtual function, it becomes an abstract base class. Objects of this class type cannot be instantiated directly, as they lack implementation for one or more functions.
- Derived Class from Abstract Base Class: If a derived class inherits from an abstract base class and provides implementations for all pure virtual functions, it is considered a concrete class and can be instantiated.
- Polymorphism: Public inheritance enables polymorphic behavior. A derived class object can be referenced or pointed to by a base class pointer, allowing you to interact with it through the base class interface.
- Type Identity: Despite inheritance, a derived class object is not converted into an abstract base class object; it remains an instance of the derived class. However, through polymorphism, it can be accessed and manipulated via a base class interface.
In summary, public inheritance enables derived classes to be treated polymorphically as instances of their base class, but they remain concrete implementations, not instances of the abstract base class.
This is called "IS-A" inheritance; it is also referred to as
interface inheritance. There exists an "IS-A" relationship between a class and the interface that it implements.
interface Maintainable{
abstract void clean();
}
public class House implements Maintainable{
static int counter = 0;
public void clean() {
counter++;
System.out.println("Cleaning House: counter = " + counter);
}
public static void main(String[] args) {
House h1 = new House();
h1.clean();
Maintainable m1 = new House();
m1.clean();
boolean state = m1 instanceof House;
System.out.println("state = " + state);
}
}
/*
Program output
Cleaning House: counter = 1
Cleaning House: counter = 2
state = true
*/
The instanceof operator says that m1 of type 'Maintainable' is a 'House' because the value of the variable state is true.
Class hierarchies should be about interface inheritance. In the classic example, a parent class Shape describes the properties and behaviors of all shape types using virtual and
pure virtual member functions. The derived classes like circle implement the specifics. The Circle is a Shape.
This module explored the fundamentals of inheritance and pure polymorphism, including the use of derived classes and virtual functions to create a class hierarchy. You learned:
- What inheritance is and why it is so important to the object-oriented programming paradigm
- What virtual member functions are and how they are used
- How to derive a class from a base class and create a class hierarchy
- How public inheritance implements an ISA relationship between a derived class and the base class
- How a reference to the derived class may be implicitly converted to a reference to the public base class
- What pure virtual functions are and why they are useful in creating abstract base classes
- The uses of the C++-specific cast operators
- How to use Runtime Type Identification (RTTI) to safely determine the type pointed at by a base class pointer at runtime
- How to code exceptions to catch unexpected conditions
Inheritance is a mechanism for enhancing existing, working classes. If a new class needs to be implemented and a class representing a more general concept is already available, then the new class can inherit from the existing class. For example, suppose we need to define a class Manager. We already have a class Employee, and a manager is a special case of an employee. In this case, it makes sense to use the language construct of inheritance. Here is the syntax for the class definition:
class Manager : public Employee{
public:
new member functions
private:
new data members
};
The : symbol denotes inheritance. The keyword public is required for a technical reason.
The existing, more general class is called the base class. The more specialized class that inherits from the base class is called the derived class.
In our example, Employee is the base class and Manager is the derived class.
In the Manager class definition you specify only new member functions and data members.
All member functions and data members of the Employee class are automatically inherited by the Manager class.
For example, the set_salary function automatically applies to managers:
Manager m;
m.set_salary(68000);