Interface Segregation Principle (ISP)
The Interface Segregation Principle says that no code should depend on methods that it doesn’t use.
Core ideas:
- We prefer many small interfaces over one larger, more complicated interface
- If a class has many functionalities, each client of the class should only see the functionality that it needs
Example
Example: Video Game (No NVI for simplicity)
Imagine we make a change to our drawing interface
battlefield.cc
must still recompile, even though it’s not using any part of the drawing interface- Needless Coupling between
UI
andBattlefield
viaEnemy
One solution: Multiple Inheritance
Somewhat similar to the Adapter Pattern - used when a class provides an interface different from the one you need.
For example - Library
for our window - expects objects to inherit from “Renderable” and provide a “render” method.
Don’t want to change all of our inheritance hierarchy, or all our draw calls to render - violates open / closed, pain. Use an adapter class.
- Satisfy the
Renderable
interface by calling the methods we’ve already defined. - We might not even need our Adapter to provide this “draw” method anymore, just render. In which case, we could use Private Inheritance.
Protected and private inheritance are not is-a (Specialization) relationship.
As such, we cannot use classes with private or protected inheritance polymorphically.
Multiple inheritance can have some tricky semantics.
Ambiguous - it’s not clear whether A1::foo
or A2::foo
should be called - b.foo()
doesn’t compile. Disambiguate: b.A1::foo()
or b.A2::foo()
Question
Can you do this if
b
inherits from a single class, sayclass B: public A
, can you doB.A::foo()
?Although not needed, yes you can do this! It’s using the Scope Resolution Operator.
Another tricky aspect of multiple inheritance - shared base class. ”Diamond Problem”, “deadly diamond of death”.