SOLID jest to zestaw zasad dobrego programowania obiektowego. Stanowią fundament projektowania oprogramowania które mogą pomóc programistom tworzyć bardziej zorganizowane, elastyczne i łatwe w utrzymaniu systemy.
Trzecia zasada SOLID jest to zasada podstawienia Liskov (ang. Liskow substitution) sformułowana przez Barbarę Liskov.
Jaka jest Definicja ?
Zgodnie z zasadą podstawienia Liskov w miejscu klasy bazowej można użyć dowolnej klasy potomnej. W związku tym, niezależnie od tego czy zostanie wywołana klasa bazowa czy klasa potomna program powinien zachowywać się zgodnie z oczekiwaniami.
Jak to osiągnąć?
Klasy potomne powinny zawierać te same metody co klasa bazowa aby każda klasa mogła wykorzystywać wszystkie metody bez konieczności ich przesłaniania. Należy zwrócić szczególną uwagę na zgodność interfejsów i metod.
Przykład zaprezentowany poniżej jest nie zgodny z zasada podstawienia Liskov. Klasa Latte dziedziczy po klasie Kawa wszystkie metody. Została zatem obarczona implementacją metody dodajMleko() znajdującej się w klasie bazowej, której nie wykorzystuje. Klasy pochodne nie powinny nadpisywać metod klas bazowych a jedynie je rozszerzać, wywołując metodę z klasy bazowej.
public class Kawa {
public void przygotujKawe(){
dodajKawę();
dodajWodę();
dodajMleko();
}
protected void dodajKawę(){
System.out.println("Kawa");
};
protected void dodajWodę(){
System.out.println("Woda");
};
protected void dodajMleko(){
System.out.println("Mleko");
};
}
public class Latte extends Kawa {
@Override
public void przygotujKawe() {
super.przygotujKawe();
}
}
public class Americano extends Kawa{
@Override
public void przygotujKawe() {
super.przygotujKawe();
}
@Override
public void dodajMleko() {
System.out.println(""); //Kawa nie powinna mieć mleka
}
}Poniżej został zaprezentowany przykład poprawnego zastosowania 3 zasady SOLID. Klasa bazowa Kawa może zostać wywołana zamiast klasy pochodnej KawaMleczna. Ponadto, stosując polimorfizm, klasy potomne wykorzystują metody bazowe (poprzez słowo kluczowe super). Żadna z metod klas potomnych nie nadpisuje metod klasy bazowej.
public class Kawa{
public void przygotujKawe(){
dodajKawę();
dodajWodę();
}
...
}
public class KawaMleczna extends Kawa{
public void przygotujKawe() {
super.przygotujKawe();
dodajMelko();
}
}
public class Latte extends KawaMleczna{
@Override
public void przygotujKawe() {
super.przygotujKawe();
}
}
public class Americano extends Kawa{
@Override
public void przygotujKawe() {
super.przygotujKawe();
}
}
public class App
{
public static void main( String[] args )
{
Kawa kawa;
kawa= new Latte();
kawa.przygotujKawe();
kawa = new Americano();
kawa.przygotujKawe();
kawa = new KawaMleczna();
kawa.przygotujKawe();
}
}