我知道我遲到了,但答案並沒有真正解決實際問題。
問題是PHP不支持函數/方法重載。以無類型語言支持函數重載將會很困難。
暗示有幫助。但在PHP中是非常有限的。不知道爲什麼。例如,你不能提示一個變量是一個int或布爾值,但數組很好。去搞清楚!
其他面向對象的語言使用函數重載來實現這一點。也就是說功能的簽名明顯不同。
因此,舉例來說,如果下面是可能的,我們不會有問題
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
當然,當它來構造的PHP開發人員意識到他們必須實現它,喜歡還是不喜歡!所以他們只是在第一種情況下抑制錯誤或不提高它。
這是愚蠢的。
一個熟人曾經說過PHP實現的對象只爲實現命名空間的一種方式。現在我不太那麼批評,但是一些做出的決定傾向於支持這一理論。
我總是有最大的警告變成開發代碼的時候,我從來沒有讓一個警告,去了不理解這意味着什麼,什麼樣的影響是。我個人不關心這個警告。我知道我想要做什麼,PHP並沒有做到這一點。我來到這裏尋找一種方法來選擇性地抑制它。我還沒有找到方法。
所以我會陷入這個警告並且自己壓制它。羞愧我需要這樣做。但我對STRICT嚴格要求。
我不同意這裏的兩點:「如果Bar是Foo的一個子類型,那麼Foo類型的對象可能被Bar類型的對象替代(反之亦然)」。反之則不成立;你不希望在任何使用sublcass的地方使用超類。另一件事是關於LSP:如果參數是逆變的,那麼類型是受尊重的。如果PHP是純粹的OO,那麼就沒有問題了,因爲Array比Object更窄(假設聲明中沒有任何類型意味着任何對象)。因此bar()的實現在Baz中更加通用,使它適合LSP –
@AndrésFortier反之亦然,我的意思是在Foo的範圍內,Foo和Bar應該是可以互換的。然而關於第二個話題,我同意你的看法。 Kaern給出的例子不違反LSP,因爲Baz :: bar()可以安全地替代Foo :: bar()。 – Tivie
非常好的解釋,謝謝。那麼爲什麼我可以在構造函數中打破Liskov原理呢? –