【问题标题】:PHP Duck Sample - Head First - Design Patterns - Chapter OnePHP Duck 示例 - Head First - 设计模式 - 第一章
【发布时间】:2011-04-14 14:13:08
【问题描述】:

这是我向许多其他人提出的第一个问题。

这里有人可能会说我疯了,因为我正在使用 PHP-OO 关注问题标题中提到的书。

在第一章中,作者介绍了一个名为“SimUDuck”的简单项目,虽然我在 Java 中重现了相同的项目,但我想用 PHP 重现相同的项目。

最后,SimUDuck 的项目创建了两 (2) 个接口(FlyBehavior 和 QuackBehavior)、超过五 (5) 个实现这些接口的类(例如 FlyWithWings()、Quack() 等)、一个名为 Duck 的抽象类和三 (3) 或四 (4) 种不同的鸭子种类类扩展 Duck(Mallard、HeadRedDuck、RubberDuck 等),只是为了演示接口编程的重要性。

为了模拟 Java 主方法环境,我创建了一个名为 MiniDuckSimulator 的 PHP 类,包括函数“public static function main()”,并在同一个脚本中添加了“MiniDuckSimulator::main();” .该脚本可以正常工作。

有趣的问题是,在没有调用任何 QuackBehavior::quack() 实现的方法的情况下,echo 'Quack!quack!'出现。读过这本书的人都知道我在说什么。

注意:以下是脚本的特定部分:


interface FlyBehavior {
    public function fly();
}

interface QuackBehavior {
    public function quack();
}

include_once 'FlyBehavior.php';

class FlyWithWings implements FlyBehavior {

    public function fly() {
        echo 'I'm flying!<br />';
    }

}

include_once 'QuackBehavior.php';

class Quack implements QuackBehavior {

    public function quack() {
        echo 'Quack!<br />';
    }
}

abstract class Duck {

    protected $flyBehavior;
    protected $quackBehavior;

    function  __construct() {
    }

    public function performFly(){
        $this->flyBehavior->fly();

    }

    public function performQuack(){
        $this->quackBehavior->quack();

    }

    public function setFlyBehavior($flyBehavior){
        $this->flyBehavior = $flyBehavior;
    }

    public function swim(){
        echo "All the ducks float, including the decoy!<br />";
    }
}

include_once 'Duck.php';
include_once 'FlyWithWings.php';
include_once 'Quack.php';

class Mallard extends Duck {

    function __construct() {
        $this->flyBehavior = new FlyWithWings();
        $this->quackBehavior = new Quack();
    }

}

class MiniDuckSimulator {
    public static function main(){
        $mallard = new Mallard();
        $mallard->performFly();
    }

}

MiniDuckSimulator::main();

提前致谢。

卢克达赫。

【问题讨论】:

  • 看文字我的眼睛受伤了:-S
  • 对不起。我会简短地说,但会错过一些有兴趣帮助我的人的重要信息。
  • 双重“庸医”是没有用的。它可能是同一个方法被调用了两次,也可能是一个方法和父类的方法。我会添加一些文字,例如“quack-rubber”和“quack mallard”等。
  • 更好吗???现在,关于“code sn-ps”是不可能的,因为它大约有 10 个不同的文件。我要做的是将这些文件附加到某个地方。
  • 我们的一位同事(昵称 Macek)已经回答了这个问题。问题是 Quack 类有方法 quack(),并且由于 PHP 会将与类同名的任何方法视为类构造函数,所以当我调用“$mallard = new Quack()”时,quack()方法内容将被执行。我做的很简单……把类名改成NormalClass,就是这样。

标签: php design-patterns interface


【解决方案1】:

您看到Quack!&lt;br /&gt; 输出的原因是:

class Quack implements QuackBehavior {

    public function quack() {
        echo 'Quack!<br />';
    }
}

这是您的问题:如果您只是运行new Quack();,则quack() 方法会被php 作为构造函数自动执行,因为它与您的类同名。 -- 我看到你在你的问题中引用了 Java,所以这对你来说不应该是一个陌生的概念。

new Quack(); // => Quack!<br />

一种可能更好的方法

<?php

interface CanFly {
  public function fly();
}

interface CanQuack {
  public function quack();
}

abstract class Duck implements CanFly, CanQuack {

  protected $color = "DEFAULT"

  public function fly(){
    echo "I'm flying with my {$this->color} wings\n";
  }

  public function quack(){
    echo "I'm quacking\n";
  }

  public function swim(){
    echo "I'm swimming\n";
  }
}

class Mallard extends Duck {

  public function __construct(){
    $this->color = "green";
  }

  public function quack(){
    echo "My quack sounds more like a honk\n";
  }
}

$m = new Mallard();
$m->fly();
$m->quack();
$m->swim();

?>

输出

I'm flying with my green wings
My quack sounds more like a honk
I'm swimming

【讨论】:

  • 关于回显错误,我已经解释了原因。这是因为我是巴西人,在葡萄牙语中我们说“Estou voando!”不使用字符串中的单引号,粘贴后我将字符串翻译成英文。不要为第二个“嘎嘎!”而烦恼。我已经编辑了字符串内容以仅复制一个“嘎嘎”(这对我来说已经非常嘎嘎了!!!!:)。关于您提到的实际代码,我粘贴的代码是实际代码。
  • 如果您不打算阅读答案,我无法帮助您。您看到Quack!&lt;br /&gt; 的原因是因为您有一个函数quack(),其名称与Quack 类相同,而php 会自动将其视为构造函数。我添加了更多的编辑,可以帮助您了解如何以一种可能更好的方式执行此操作...
  • 对不起...我现在看到了,我没有看到你在横线后给出的答案,你是绝对正确的。非常感谢。我忘记了PHP会将与类同名的任何方法视为类构造函数。我所做的是将 Quack 类重命名为 NormalQuack,整个脚本运行良好。再次感谢您。
  • 我认为这不是一个更好的方法,因为他在谈论 Head First - Design Patterns 这本书,在书中这个例子是关于不在鸭子类中实现 quack 和飞行,因为橡皮鸭不能飞例如。他们建议创建接口和类并为此操作,然后使用 Duck 类的构造函数中的对象。
【解决方案2】:

在您的情况下,我个人认为,当我在没有调用该方法的情况下在代码中达到回声时,我忽略了一些事情。我看不出有什么方法可以做到。

重新分析您的代码并寻找一种偷偷摸摸的方式来让您的回声“嘎嘎!嘎嘎!”正在到达。

【讨论】:

  • 首先,感谢您的快速回复。虽然可能不够,但下面是“function main()”的内容: $malard = new Mallard(); $mallard->performFly(); //仅此而已。
  • 首先,上述 cmets 要求您分解问题,而不是缩小问题。太难读了。其次,众所周知,鸭子在出生或飞行时会发出嘎嘎声。我开玩笑。但说真的,必须有一些东西调用你的方法,其中包含'echo'语句。它不会调用自己。必须忽略一些事情。
  • 我希望这个问题现在变得更好阅读。如果您已阅读本书并使用 Java 测试过相同的示例(我相信您做过),那么您唯一需要做的就是用 PHP 替换 Java 命名空间(例如“System.out.println”,void)和声明,仅此而已。 (当然,如果你有空的话)。
  • 我没看过这本书。我的回答是建议用批判性思维来解决你的问题。遇到问题 --> 假设您的错误 --> 查找并修复错误。我希望我能帮助你更多。
  • "遇到问题 -->" 我试过了!!! “假设你的错误->”我从昨天开始就假设并且我没有找到解决方案,这就是我问这个问题的原因之一。 “发现并修复错误”,如果我还没有用尽我脑海中出现的所有可能性,再次,我没有问这个问题并在成员心中带来了这么多的疑问。
【解决方案3】:

评论这一行:

echo 'Quack!<br />';

你还看到庸医吗?如果是这样,那么您的代码中有一个带有此字符串的 echo/exit/die!

【讨论】:

  • 这只是一个庸医!!!我已经编辑了回声结果,只复制了一个。这是因为在本书样本中,作者因为他们非常喜欢鸭子,所以他们用两 (2) 个“嘎嘎!”编写了“System.out.println”。没关系。
【解决方案4】:

这是因为当你有同名的方法的类时,PHP 将其视为构造函数。这已经在 php 7 中被弃用,并且很快就会停止。您可以在在线文档中看到它:http://php.net/manual/en/migration70.deprecated.php

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多