Załóżmy, że mam interfejs FooInterface
z następującą sygnaturą:
interface FooInterface {
public function doSomething(SomethingInterface something);
}
I konkretna klasa, ConcreteFoo
która implementuje ten interfejs:
class ConcreteFoo implements FooInterface {
public function doSomething(SomethingInterface something) {
}
}
Chciałbym ConcreteFoo::doSomething()
zrobić coś wyjątkowego, jeśli przejdzie on przez specjalny typ SomethingInterface
obiektu (powiedzmy, że się nazywa SpecialSomething
).
Zdecydowanie jest to naruszenie LSP, jeśli wzmocnię warunki wstępne metody lub wyrzucę nowy wyjątek, ale czy nadal byłoby to naruszenie LSP, jeśli stworzę SpecialSomething
obiekty specjalne , zapewniając rezerwę dla SomethingInterface
obiektów ogólnych ? Coś jak:
class ConcreteFoo implements FooInterface {
public function doSomething(SomethingInterface something) {
if (something instanceof SpecialSomething) {
// Do SpecialSomething magic
}
else {
// Do generic SomethingInterface magic
}
}
}
doSomething()
metody byłaby konwersja typu naSpecialSomething
: jeśli ją otrzymaSpecialSomething
, po prostu zwróci obiekt niezmodyfikowany, natomiast jeśli otrzymaSomethingInterface
obiekt ogólny , uruchomi algorytm, aby przekonwertować go naSpecialSomething
obiekt. Ponieważ warunki wstępne i dodatkowe pozostają takie same, nie sądzę, aby umowa została naruszona.