I'm working with SOLID principles, specifically Liskov's Substitution Principle (LSP).
I have an abstract class called Button that defines different methods and different subclasses extend it to define some of those methods. For example I have a subclass called PauseButton that implement only 3 methods from the abstract class.
Is that concidered a violation of LSP?
CodePudding user response:
The core idea of Liskov's Substitution Principle is that you could use instances of the subtype whenever you may use instances of the type. The subtype may be more specialized but it should comply with the same contract.
In your example, PauseButton fulfills LSP with regard to Button if all its "methods" (we say "operations" in UML) comply with the contract defined for Button. It's not just about implementing the methods but making sure that the methods are compatible:
PauseButtonmay not strengthen the preconditions ofButton. I.e. if the conditions are fulfilled to perform aButtonmethod, you should be able to perform the corresondingPauseButtonmethod as well.PauseButtonmay not weaken the postconditions ofButton. I.e. ifButtonmakes some promises about a method,PauseButtonmust fulfill at least the same promises.- Invariants of
Button(logical conditions that should be always true) should also be invariants ofPauseButton.PauseButtonmay have additional invariants. - History constraint: roughly speaking, it means that whereas
PauseButtonis aButton,PauseButtonmethods should not modify directly itsButtonstate, without using methods of theButton. No shortcut.
In the case of abstract subclasses, it's more delicate to verify LSP since we cannot look at direct instances. Nevertheless, the subclasses could be indirectly instantiated by concrete subclasses that provide the missing methods:
- If at least one of the three
PauseButtonmethods that you implement infringes LSP (i.e. are incompatible with the same method fromButton), thenPauseButtonviolates LSP. - But if all the three methods are compliant, and if
PauseButtondoes not redefine the contract of the other methods, you can assume thatPauseButtonis LSP-Compliant : you could create a concrete subclass ofPauseButtonthat would be compliant, even if at the present stage such sublass doesn't exist. This fulfills the requirements for interchangeability.
