2014-12-24 30 views
2

我不太明白指示類的名稱,你會注入另一個類,如的好處,PHP - 可捕捉的致命錯誤:傳遞給Too的參數1必須是Foo的實例,Boo的實例給出了嗎?

public function __construct(Foo $Foo) 

我可以在這種情況下看到它的好處,

class Foo 
{ 
    public $message = 'foo'; 
} 

class Boo 
{ 
    public $message = 'boo'; 
} 

class Too 
{ 
    public function __construct(Foo $Foo) 
    { 
     $this->Foo = $Foo; 
    } 

    public function fetch() 
    { 
     return $this->Foo->message; 
    } 
} 

$Too = new Too(new Boo); 
var_dump($Too->fetch()); 

我會得到這個錯誤,

Catchable fatal error: Argument 1 passed to Too::__construct() must be an instance of Foo, instance of Boo given, called in C:...

但是,如果我改變

class Boo 
{ 
    public $message = 'boo'; 
} 

class Boo extends Foo 
{ 
    public $message = 'boo'; 
} 

我會得到正確的結果,如果沒有錯誤,

string 'boo' (length=3) 

但是,意義或語義的Foo $Foo已經崩潰。因爲我實際上是通過$Boo

$this->Foo->message;的語義也不存在了,因爲我現在正在閱讀$message$Boo。但是這個$this->Foo->message;說我在讀$message$Foo ...

這是PHP的缺陷嗎?否則,你會如何解釋?這是否也發生在其他語言(如Java或Python)?

回答

5

這將在所有語言中發生,因爲它是OOP的一部分。 它的實際使用將以strategy pattern爲例。

interface Mammal 
{ 
    public function walk(); 
} 

class Human implements Mammal 
{ 
    public function walk() 
    { 
     echo 'Walk using two legs or whatever'; 
    } 
} 

class Cat implements Mammal 
{ 
    public function walk() 
    { 
     echo 'Walk using four legs or whatever'; 
    } 
} 

function performWalk(Mammal $mammal){ 
    $mammal->walk(); 
} 

現在的概念是,我要的是哺乳動物,我不在乎它是人類或貓或其他任何東西,因爲它是不是類責任,知道什麼樣的實現確實是哺乳動物有。

因此,要回答你的問題>>>>這是不是一個錯誤,它是一個功能:) < < < < <

+0

Aww,這是有道理的。所以'$ mammal-> walk();'會在'Human'或'Cat'中迴應'walk'嗎? – laukok

+1

作爲一個預約功能,你並不在乎。誰打電話給那個功能的人有責任知道它需要傳遞什麼樣的實例 –

+0

明白了!非常感謝你! :) – laukok

3

類傳遞中必須滿足美孚的要求。如果Boo擴展Foo,PHP認爲Boo滿足Foo的所有要求。並非所有的語言都會接受繼承了被調用的類的類,但在PHP中這是正確的。通常,人們將實現一個接口,並且該類可以接受任何實現該接口的類。這樣,如果您決定您的原始類Foo已損壞,則可以將其替換爲實現相同界面的另一個類。

如果你想通過Boo而Boo與Foo沒有任何關係,那麼Too應該使用構造函數public function __construct(Boo $ Boo)來定義,否則你不會使用它來實現它的目的。

我希望有幫助。

+0

非常感謝。 – laukok

相關問題