Чи застосовується Принцип заміщення Ліскова також для класів, що реалізують інтерфейс?


17

LSP заявляє, що класи повинні бути замінними для їх базових класів, тобто похідні та базові класи повинні бути семантично еквівалентними.

Але чи застосовується також LSP для класів, що реалізують інтерфейс? Іншими словами, якщо метод інтерфейсу, реалізований класом, семантично відрізняється від того, що очікує, що це буде користувач, чи вважатиметься це порушенням LSP?


7
Так. Точно ті самі причини і результати, як порушення LSP, якщо це інтерфейс, абстрактний клас, повний клас, не має значення. LSP полягає у встановленні та задоволенні очікувань, щоб дозволити споживачам взагалі ставитися до ваших типів.
Джиммі Хоффа

5
За великим рахунком (я знаю відмінності, але я тут узагальнюю) інтерфейси дещо аналогічні чистим абстрактним класам (термін C ++), і тому Ліскову слід застосовувати інтерфейси та класи, які їх реалізують.
Jesse C. Slicer

3
Зверніть увагу: формулювання LSP, з яким я знайомий, говорить про підтипи, а не про похідні та базові класи. Я маю на увазі, тому що жодна з причин не є специфічною для успадкування і застосовується так само добре, як і для будь-якого іншого типу підтипів.

Відповіді:


17

якщо метод інтерфейсу, реалізований класом, семантично відрізняється від того, що очікує, що це буде користувач, чи вважатиметься це порушенням LSP?

Якщо реалізація семантично відрізняється від поведінки, задокументованої через інваріанти інтерфейсу, та його попередніх та пост-умов, то відповідь "так", це було б порушенням LSP. Принцип встановлює правила абстракції та його реалізацію, не вимагаючи присутності сторони абстракції у формі класу.

Однак якщо ми говоримо про те, чого очікують користувачі , відповідь буде "не обов'язково": користувачі мають право на помилкові очікування.


"Якщо реалізація семантично відрізняється від поведінки, задокументованої через інваріанти інтерфейсу". Чи могли б ви детальніше пояснити, що ви маєте на увазі під "інваріантами інтерфейсу"?
користувач1483278

3
@ user1483278 Ось стаття про типи інваріантів . Стаття називає їх "Класовими інваріантами", але опис стосується і інтерфейсів. Інваріанти - це умови, які встановлюються при будівництві та підтримуються протягом усього періоду дії екземпляра. Наприклад, якщо інтерфейс має властивість, Nameяку не можна встановити null, то, obj.Name != nullяк кажуть, є інваріантом цього інтерфейсу.
dasblinkenlight

1
Зазвичай, коли обговорюються інваріанти, можна написати фрагмент коду, щоб переконатися, що інваріант підтримується протягом усього терміну експлуатації об'єкта. Однак, як правило, простіше описувати інваріант простою англійською мовою.
rwong
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.