Ответ
Такое изменение может нарушить Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP).
Суть LSP: Объекты подкласса должны быть заменяемы на объекты родительского класса без изменения корректности программы. Поведение подкласса должно соответствовать контракту (ожиданиям) базового класса.
Нарушение при добавлении метода:
- Сужение предусловий: Новый метод в подклассе может накладывать более строгие условия для работы, чем ожидается от родителя.
- Расширение постусловий: Метод может гарантировать меньше, чем метод родителя.
- Нарушение инвариантов: Метод может изменять состояние объекта способом, недопустимым для родительского класса.
Классический пример нарушения LSP:
class Rectangle {
protected int width, height;
public void setWidth(int w) { width = w; }
public void setHeight(int h) { height = h; }
public int getArea() { return width * height; }
}
class Square extends Rectangle {
// Нарушение LSP: изменяет контракт методов setWidth/setHeight.
@Override
public void setWidth(int w) {
super.setWidth(w);
super.setHeight(w); // Неожиданное побочное действие!
}
@Override
public void setHeight(int h) {
super.setHeight(h);
super.setWidth(h); // Неожиданное побочное действие!
}
}
// Клиентский код, работающий с Rectangle, сломается для Square.
void testArea(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
assert r.getArea() == 20; // Успех для Rectangle, провал для Square (получится 16).
}
Вывод: Добавление метода, которое меняет семантику или инварианты унаследованного поведения, нарушает LSP. Часто это сигнал к пересмотру иерархии наследования в пользу композиции.
Ответ 18+ 🔞
Да ты посмотри, какая тонкая хуйня всплывает! Вроде просто метод добавил в наследника — ну и что? А нихуя! Это же прямое нарушение Принципа подстановки Барбары Лисков, ёпта!
В чём соль, блядь: Если у тебя есть родительский класс, то на любой его объект должен спокойно садиться любой объект-потомок, и программа не должна обосраться. Потомок должен вести себя в рамках контракта родителя, а не выёбываться.
А как можно наебнуться, добавив метод?
- Ужесточить входные требования (предусловия). Родитель метод принимал
int, а ты в наследнике говоришь: «А мне только положительные!». Клиентский код, рассчитанный на родителя, подаст тебе отрицательное — и ты ему в ответ исключение в ебальник. Непорядок. - Ослабить гарантии (постусловия). Родительский метод клялся, что после его вызова объект будет в валидном состоянии. А твой новый метод в наследнике может этот инвариант разъебать.
- Просто сломать инварианты класса. Это когда твой новый метод начинает менять внутреннее состояние так, как родитель себе никогда не позволял.
Вот тебе классический пиздец на примере, прямо в рот:
class Rectangle { // Прямоугольник, блядь
protected int width, height;
public void setWidth(int w) { width = w; }
public void setHeight(int h) { height = h; }
public int getArea() { return width * height; }
}
class Square extends Rectangle { // Квадрат, сука
// А вот тут начинается пиздец. Нарушаем LSP напрочь.
@Override
public void setWidth(int w) {
super.setWidth(w);
super.setHeight(w); // АХА! Нежданчик, блядь! Меняю и высоту тоже!
}
@Override
public void setHeight(int h) {
super.setHeight(h);
super.setWidth(h); // И тут то же самое, ёбта!
}
}
// А теперь смотри, как клиентский код, который работал с Rectangle, ебётся:
void testArea(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
assert r.getArea() == 20; // Для прямоугольника — ок. Для квадрата — ПИЗДЕЦ! Получится 16, и тест провалится.
}
Вывод, блядь: Если добавление метода в наследнике ведёт к тому, что он начинает себя вести не так, как от него ожидают исходя из типа родителя — это пиздец и нарушение LSP. Часто такой сигнал кричит: «Бро, перестань ебаться с наследованием, может, тут композиция нужна?».