Home > Enterprise >  Do abstract subclasses of an abstract superclass violate LSP?
Do abstract subclasses of an abstract superclass violate LSP?

Time:02-16

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:

  1. PauseButton may not strengthen the preconditions of Button. I.e. if the conditions are fulfilled to perform a Button method, you should be able to perform the corresonding PauseButton method as well.
  2. PauseButton may not weaken the postconditions of Button. I.e. if Button makes some promises about a method, PauseButton must fulfill at least the same promises.
  3. Invariants of Button (logical conditions that should be always true) should also be invariants of PauseButton. PauseButton may have additional invariants.
  4. History constraint: roughly speaking, it means that whereas PauseButton is a Button, PauseButton methods should not modify directly its Button state, without using methods of the Button. 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 PauseButton methods that you implement infringes LSP (i.e. are incompatible with the same method from Button), then PauseButton violates LSP.
  • But if all the three methods are compliant, and if PauseButton does not redefine the contract of the other methods, you can assume that PauseButton is LSP-Compliant : you could create a concrete subclass of PauseButton that would be compliant, even if at the present stage such sublass doesn't exist. This fulfills the requirements for interchangeability.
  • Related