Liskov Substitution Principle

"There are two parts to learning craftsmanship: knowledge and work." - Robert C. Martin

Liskov Substitution Principle

Liskov

The Liskov substitution principle tells us that any derived class can be used in a base class location. Hence the interface and all methods must be maintained. This rule is consistent with open/closed principle, as the derived class does not affect the behavior of the parent class. This means that derived classes must be substitutable in relation to the base classes.This breaks most often in three cases. When the inheritance mechanism has been misplaced and the polymorphic interface is too general. When inheritance without a polymorphism mechanism was applied. When derived classes override methods of the base class, replacing its unadulterated logic. In the mechanism of inheritance, there should not be a situation where derived classes override methods of the base class. They should possibly expand them. The following program breaks the LSP, due to fact that the Basenji class can not replace the base Dog class. The Dog class will enforce the implementation of the bark() method. It is illogical to use the Basenji class, because it is the only breed of dogs that does not bark.

class Dog
{
public function bark()
{
echo 'Woow woow!;
}

public function move()
{
echo 'I am running!;
}
}

class GermanShepherd extends Dog
{
}

class Basenji extends Dog
{
}

$dog = new Basensji();
$dog -> bark();
$dog -> move();

A good solution is to use additional classes that will divide the dog breed into barking and non-barking breeds. The BarkingDogs class and the NonBarkingDogs class inherits the move() method from the Dog class. The bark() method is assigned only to the BarkingDogs class. The German Shepherd barked, which is why the GermanShepherd class inherits from the BarkingDogs class, and the Basenji class after the NonBarkingDogs class. The correct application of the Liskov substitution rule is outlined below:

class Dog
{
public function move()
{
echo 'I am running!;
}
}

class BarkingDogs extends Dog
{
public function bark()
{
echo 'Woow woow!;
}
}

class NonBarkingDogs extends Dog
{
}

class GermanShepherd extends BarkingDogs
{
}

class Basenji extends NonBarkingDogs
{
}

$dog = new Basensji();
$dog -> bark();
$dog -> move();