I'm working with solid priciple, 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 that the base type, but it should comply with the same contract.
In your example, PauseButton fulfills LSP with a 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 constraints is more complicated, but roughtly speaking, it means that since
PauseButtonis aButton, aPauseButtonmethod should not modify directly the state of theButtonit is, without using methods of theButton. No shortcut.
In the case of abstract classes, it's more delicate to verify LSP: not all the methods are defined, so we cannot look at direct instances. Nevertheless, the classes could be indirectly instantiated using concrete classes that provide the missing methods:
- If at least one of the three
PauseButtonmethods that you implement infringes LSP (are incompatible with the same method fromButton), thenPauseButtonis not compliant. - 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.
