Wiem, że spóźniam się na imprezę, ale odpowiedzi nie wyjaśniają rzeczywistego problemu.
Problem polega na tym, że PHP nie obsługuje przeciążania funkcji/metod. Trudno byłoby wspierać przeciążanie funkcji w języku bez typu.
Podpowiedź pomaga. ale w PHP jest bardzo ograniczony. Nie pewny dlaczego. Na przykład nie możesz wskazać, że zmienna to int lub Boolean, ale tablica jest w porządku. Domyśl!
Inne języki zorientowane obiektowo realizują to przy użyciu funkcji przeciążania. Co oznacza, że podpis funkcji jest oczywiście inny.
Tak na przykład, jeśli następuje to możliwe, że nie będzie miał problemu
class Foo
{
public function bar(Array $bar){
echo "Foo::bar";
}
}
class Baz extends Foo
{
public function bar(int $bar) {
echo "Baz::bar";
}
}
$foo = new Baz();
$bar = new Baz();
$ar = array();
$i = 100;
$foo->bar($ar);
$bar->bar((int)$i);
would output
Foo::bar
Baz::bar
Oczywiście, gdy przyszło do konstruktorów programiści php sobie sprawę, że trzeba go wdrożyć, podoba czy nie! Po prostu tłumią błąd lub nie podnoszą go w pierwszym przypadku.
Co jest głupie.
Kiedyś znajomy PHP zaimplementował obiekty tylko jako sposób implementacji przestrzeni nazw. Teraz nie jestem aż tak krytyczny, ale niektóre z podjętych decyzji mają tendencję do popierania tej teorii.
Zawsze mam włączone maksymalne ostrzeżenia podczas tworzenia kodu, nigdy nie pozwolę, aby ostrzeżenie przeszło bez zrozumienia, co to oznacza i jakie są tego konsekwencje. Osobiście nie obchodzi mnie to ostrzeżenie. Wiem, co chcę zrobić i PHP nie robi tego dobrze. Przyszedłem tutaj, szukając sposobu, aby go selektywnie stłumić. Jeszcze nie znalazłem sposobu.
Więc zatrzymam to ostrzeżenie i stłumię je. Wstyd, muszę to zrobić. ale ja jestem surowy w odniesieniu do STRICT.
Nie zgadzam się z dwiema rzeczami tutaj: "jeśli Bar jest podtypem Foo, obiekty typu Foo mogą być zastąpione obiektami typu Bar (i na odwrót)". Część vice versa nie trzyma; nie spodziewasz się używać superklasy w żadnym miejscu, w którym używana jest podlaska. Inna sprawa dotyczy LSP: jeśli parametry są sprzeczne, to typy są respektowane. Gdyby PHP było czystym OO, wtedy nie byłoby problemu, ponieważ Array byłby węższy niż Object (zakładając, że żaden typ w deklaracji nie oznacza żadnego obiektu). Tak więc implementacja bar() byłaby bardziej ogólna w Baz, dzięki czemu pasowałaby do LSP –
@ AndrésFortier. Na odwrót miałem na myśli, że w zakresie Foo, Foo i Bar powinny być wymienne. Jednak jeśli chodzi o drugi temat, zgadzam się z tobą. Przykład podany przez Kaern nie narusza LSP, ponieważ Baz :: bar() może bezpiecznie zastąpić Foo :: bar(). – Tivie
Bardzo dobre wyjaśnienie, dzięki. Więc dlaczego mogę złamać zasadę Liskov w konstruktorze? –