Search code examples
oopliskov-substitution-principle

Java LSP "derived object can substitute base object"


Regarding the Liskov Substitute Principle (LSP) it states that an object of a derived class can substitude it's base classes-object without the program failing to execute.

What if my parent class is an abstract base class with function:

public abstract class BaseClass {
    public void heal() {
        health++;
    }
}

Can I override the heal-method in a derived class and it's still valid to LSP-principle e.g.:

public class ChildClass extends BaseClass {
   @Override public void heal() {
   super.heal();
   super.heal();
}

The Programm will still execute and I can pass ChildClass-Objects to a method that expects a BaseClass-Object as a parameter. However, the two heal()-methods behave slighty different.

Can I overwrite concrete methods of abstract base classes in their child-classes without hurting LSP?


Solution

  • You can implement any logic in the derived class methods as long as the base class contracts are respected. Contracts are guarantees provided by classes and their methods and usually described in documentation. Some languages provide more formalistic contract specification, e.g. compile time assertions. The method signature could be considered as a part of the contract as well.

    If your heal method is documented as "Add one point to the object's health", then other classes which use your BaseClass rely on adding only one point. In this case overriding heal to add any other amount to the health breaks the contract and violates LSP.

    Conversely, if heal is a method which "Adds some points to the object's health", then other classes are not allowed to make any suggestions on what the added amount actually is -- the only thing they can rely on is, for example, that health after calling this method is not less than health before calling heal. In this case your override does not violate LSP and does not break the program.