2014-12-24 28 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

相关问题