Давайте проиллюстрируем на Java:
class TrasportationDevice
{
String name;
String getName() { ... }
void setName(String n) { ... }
double speed;
double getSpeed() { ... }
void setSpeed(double d) { ... }
Engine engine;
Engine getEngine() { ... }
void setEngine(Engine e) { ... }
void startEngine() { ... }
}
class Car extends TransportationDevice
{
@Override
void startEngine() { ... }
}
Здесь нет проблем, верно? Автомобиль определенно является транспортным устройством, и здесь мы видим, что он переопределяет метод startEngine () своего суперкласса.
Давайте добавим еще одно транспортное средство:
class Bicycle extends TransportationDevice
{
@Override
void startEngine() /*problem!*/
}
Сейчас все идет не так, как планировалось! Да, велосипед - это транспортное средство, однако у него нет двигателя, и поэтому метод startEngine () не может быть реализован.
Это те виды проблем, которые нарушают подстановку Лискова
Принцип приводит к, и они чаще всего могут быть признаны
метод, который ничего не делает или даже не может быть реализован.
Решением этих проблем является правильная иерархия наследования, и в нашем случае мы решили бы эту проблему путем дифференциации классов транспортных устройств с двигателями и без них. Даже если велосипед - это транспортное средство, у него нет двигателя. В этом примере наше определение транспортного устройства неверно. У него не должно быть двигателя.
Мы можем реорганизовать наш класс TransportationDevice следующим образом:
class TrasportationDevice
{
String name;
String getName() { ... }
void setName(String n) { ... }
double speed;
double getSpeed() { ... }
void setSpeed(double d) { ... }
}
Теперь мы можем расширить TransportationDevice для немоторизованных устройств.
class DevicesWithoutEngines extends TransportationDevice
{
void startMoving() { ... }
}
и расширение службы транспорта для моторизованных устройств. Здесь более уместно добавить объект Engine.
class DevicesWithEngines extends TransportationDevice
{
Engine engine;
Engine getEngine() { ... }
void setEngine(Engine e) { ... }
void startEngine() { ... }
}
Таким образом, наш класс автомобилей становится более специализированным, придерживаясь принципа подстановки Лискова.
class Car extends DevicesWithEngines
{
@Override
void startEngine() { ... }
}
И наш класс велосипедов также соответствует принципу замещения Лискова.
class Bicycle extends DevicesWithoutEngines
{
@Override
void startMoving() { ... }
}