Zasada podstawienia Liskov’a

Co to jest Zasada podstawienia Liskov’a  w programowaniu Obiektowym ?

Powiem to w jak najbardziej prostych słowach. Pewnie wielu z was zetknęło się z Zasadą podstawienia Liskov czy Liskova.  Jest to jedna z podstawowych zasad w programowaniu obiektowym (OOP).

Co to jest klasa rodzica ?

Klasa rodzica to taka, po której dziedziczą inne klasy (zwane często klasami potomnymi). Tu chyba nie ma większych problemów co ?

Co to jest klasa potomna ?

Klasa potomna w OOP to taka klasa, która dziedziczy po innej klasie (zwanej często klasą rodzica).

Poniżej zamieszczam przykład prostego dziedziczenia

Klasa rodzica : BankAccount

class BankAccount {

}

Klasa Potomna dla kasy BankAccount : SavingAccount

class SavingAccount extends BankAccount {
     private double taxRate;
}

Klasa Potomna dla klasy BasicAccount : BasicSavingAccount

class BasicSavingAccount extends SavingAccount {
     private double basicMonthlyBonus;
}

Klasa SavingAccount dziedziczy po klasie BankAccount czyli jest klasą potomną klasy BankAccount.

Klasa BasicSavingAccount dziedziczy po klasie SavingAccount czyli jest klasą potomną klasy SavingAccount ale także klasy BankAccount.

Jak działa Zasada podstawienia Liskov’a ?

Musiałem wyżej wspomnieć o dziedziczeniu gdyż tego mniej więcej dotyczy Zasada Podstawienia Liskova.

W tej zasadzie chodzi o to jak można przypisywać do siebie referencje pomiędzy klasami rodzica czy potomka.

Według zasady podstawienia Liskova, klasa Rodzica (dziedziczona) może mieć referencję do klasy Potomnej (bardziej wyspecjalizowanej , posiadającej wszystkie cechy klasy rodzica przekazane poprzez dziedziczenie) ale klasa Potomna (ta bardziej szczegółowa) nie może mieć referencji do klasy Rodzica (po tej po której dziedziczy).

Jest tak z tego powodu, że klasa dziedzicząca posiada wszelkie właściwości i metody klasy po której dziedziczy i dodatkowo ma inne właściwości (jest bardziej wyspecjalizowana). Klasa rodzica więc obiekty klasy ‘nadrzędnej’ mogą mieć referencje do obiektów klas ‘podrzędnych’ gdyż i tak odziedziczą wszystko co im trzeba bo ta klasa potomka musi to mieć tak czy siak.

Klasa Potomna jednak nie może mieć referencji to klasy Rodzica gdyż ma ona przynajmniej 1 cechę więcej niż klasa rodzica i podczas referencji będzie tego jej brakowało gdyż klasa Rodzica tego nie posiada.

Chyba jest to teraz dla ciebie dość jasne co ?

Nawiązując do przykładu podanego powyżej, obiekt klasy BankAccount może mieć referencję do obiektu klasy SavingAccount ponieważ posiada ona wszelkie odziedziczone po niej właściwości i metody.

Klasa SavingAccount jednak nie może mieć referencji do klasy BankAccount gdyż jest ona bardziej wyspecjalizowana. Klasa BankAccount nie posiada właściwości taxRate a klasa SavingAccount już ma.

Tak samo będzie na przykładzie klasy SavingAccount i BasicSavingAccount.
Klasa SavingAccount może mieć referencję do klasy BasicSavingAccount ale już odwrotnie jest to niemożliwe.

BankAccount account1account = new BankAccount()
SavingAccount account2saving = new SavingAccount()

BankAccount account3account = account2saving; #poprawna referencja 
SavingAccount account4saving = account1account; # BŁĄD !! compile-time ERROR !

Author: Seweryn

Mam na imię Seweryn i komputerami oraz informatyką interesuje się od roku 1996. Ukończyłem Birkbeck University of London na kierunku Information Technology profil Web Design. Moją kolejna wielką pasją jest gotowanie. Lubię grać w StarCrafta (od 1999 roku) , siłownię oraz moje koty. Man nadzieję, że przydadzą Ci się informacje zawarte na mojej stronie. W razie pytań pisz do mnie. Postaram się odpowiedzieć jak szybko mogę.

Leave a Reply