首先设计模式bug

时间:2015-09-24 18:46:04

标签: php

我正在研究Head First - 设计模式并将练习翻译成PHP。

我没有得到任何错误,但有一个我无法弄清楚的错误。

编辑(代码):

abstract class Cat 
{
    public $meowBehaviour, $eatBehaviour;
    function __construct(MeowBehaviour $meowBehaviour, EatBehaviour $eatBehaviour)
    {
        $this->meowBehaviour = $meowBehaviour;
        $this->eatBehaviour = $eatBehaviour;
    }
    public abstract function sits();
    public function performMeowBehaviour()
    {
        $this->meowBehaviour->meow();
    }
    public function performEatBehaviour()
    {
        $this->eatBehaviour->eat();
    }
}



interface EatBehaviour {
    public function eat();
}

class EatCatFood implements EatBehaviour {
    public function eat()
    {
        echo "I eat cat food. <br />";
    }
}

class EatGazzelle implements EatBehaviour {
    public function eat()
    {
        echo "I hunt and eat gazzelle. <br />";
    }
}

interface MeowBehaviour {
    public function meow();

}

class Meow implements MeowBehaviour {
    public function meow()
    {
        echo "meow <br />";
    }
}

class Roar implements MeowBehaviour {
    public function meow()
    {
        echo "ROAR! <br />";
    }
}

class HouseCat extends Cat
{

    function __construct()
    {
        parent::__construct(new Meow, new EatCatFood);
    }
    public function sits()
    {
        echo "if I fits I sits";
    }
}

class CatSimulator {
    public $cat;
    public function __construct()
    {
        $this->cat = new HouseCat;
        $this->cat->performMeowBehaviour();
        $this->cat->performEatBehaviour();
    }
}

$c = new CatSimulator;

CatSimulator的输出是

meow 
meow 
I eat cat food. 

我无法弄清楚为什么&#39;喵喵叫&#39;重复。

1 个答案:

答案 0 :(得分:2)

在PHP中,函数名称不区分大小写。所以这里:

class Meow implements MeowBehaviour {
    public function meow()
    {
        echo "meow <br />";
    }
}

... meow()被视为构造函数(PHP 4.x样式) - 并在$this->cat = new HouseCat;行上调用,回显第一个'meow'

当然,您可以重命名该类,但还有另一种选择:在该类中添加显式构造函数,如下所示:

class Meow implements MeowBehaviour {
    public function __construct() {}
    public function meow()
    {
        echo "meow <br />";
    }
}

现在meow方法只会被调用一次。

__construct()位于meow()之前非常重要,否则会引发E_STRICT错误。您可以阅读更多相关信息here