This chapter covers
- When to use function overriding and overloading
- The Liskov Substitution Principle
- Designing classes and subclasses properly with is-a and has-a relationships
- The Favor Composition over Inheritance Principle
- Factory classes
- Using Programming by Contract correctly when designing subclasses
As described in section 1.8, inheritance is one of the main concepts of object-oriented programming. When we create an application with class hierarchies of superclasses and subclasses, we must design the subclasses right to achieve a well-designed application.
We should know when to use function overriding or overloading. There are several design principles we can use. The Liskov Substitution Principle states that we should be able to substitute a superclass object by one of its subclass objects, and it provides additional rules to help ensure that we designed the subclasses correctly. The Favor Composition over Inheritance Principle involves making design tradeoffs between is-a relationships and has-a relationships among classes to avoid hardcoding object behaviors in the source code and instead provide the flexibility to make behavior decisions at run time. We can increase flexibility of our code further by using factory classes. If we use Programming by Contract (introduced in section 6.3) with subclasses, we must set the preconditions and postconditions of any overriding member functions correctly.