通用多态性与PHP示例 [英] General Polymorphism with PHP examples

查看:82
本文介绍了通用多态性与PHP示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于只有Dog才能玩抓取",因此此示例是一个好主意还是一个坏主意?由于使用instanceof,我怀疑这是一个非常糟糕的主意,但我不确定为什么.

As only Dogs can play "fetch", is this example a good or a bad idea? I suspect it's a really bad idea due to the usage of instanceof, but I'm not entirely sure why.

class Animal {
    var $name;
    function __construct($name) {
        $this->name = $name;
    }
}

class Dog extends Animal {
    function speak() {
        return "Woof, woof!";
    }

    function playFetch() {
        return 'getting the stick';
    }
}

class Cat extends Animal {
    function speak() {
        return "Meow...";
    }
}

$animals = array(new Dog('Skip'), new Cat('Snowball'));

foreach($animals as $animal) {
    print $animal->name . " says: " . $animal->speak() . '<br>';
    if ($animal instanceof Dog) echo $animal->playFetch();
}

另一个例子.当我不断创建具有ID的数据对象时,我认为我最好将它们全部从基类进行扩展,以避免代码重复.再说一次,这很糟糕吧?椅子没有名字,狗没有轮子.但是它们都是,因此非常混乱.

Another example. As I am constantly creating data objects that have an ID, I figured I might as well extend them all from a base class to avoid code duplication. Again, this was bad right? As a Chair doesn't have a name and a Dog doesn't have wheels. But they are both Data Objects so it's very confusing.

class Data_Object {
    protected $_id;

    function setId($id) {
        $this->_id = $id;
    }

    function getId() {
        return $this->_id;
    }
}

class Dog extends Data_Object {
    protected $_name;
    function setName($name) {
        $this->_name = 
    }

    function getName() {
        return $this->_name;
    }
}

class Chair extends Data_Object {
    protected $_numberOfWheels;
    function setNumberOfWheels($number) {
        $this->_numberOfWheels = $number;
    }

    function getNumberOfWheels() {
        return $this->_numberOfWheels;
    }
}

我想问的基本上是:所有子类应该具有相同的接口还是可以具有不同的接口?"

推荐答案

在这种情况下,讨论接口很有用.

In this context it's useful to talk about interfaces.

interface Talkative {
    public function speak();
}

class Dog extends Animal implements Talkative {
    public function speak() {
        return "Woof, woof!";
    }
}

实现健谈界面的任何动物或人类(或外星人)都可以在需要健谈的人的环境中使用:

Any animal or human (or alien) that implements the Talkative interface can be used in a context where talkative beings are needed:

protected function makeItSpeak(Talkative $being) {
    echo $being->speak();
}

这是一种正确使用的多态方法.只要它可以speak(),您都不会在乎什么 .

This is a properly used polymorphic method. You don't care what you're dealing with as long as it can speak().

如果Dog也可以进行抓取,那么对他们来说太好了.如果您想对此进行概括,也可以从接口的角度考虑它.也许有一天,您会得到一只训练有素的猫,它也可以玩抓取游戏.

If Dogs can also play fetch, that's great for them. If you want to generalize that, think about it in terms of an interface as well. Maybe one day you'll get a highly trained cat which can play fetch as well.

class Cog extends Cat implements Playfulness {
    public function playFetch() { ... }
}

此处的重点是,当您调用 playFetch()某物时,这是因为您想与该动物玩取指游戏.您之所以不致电playFetch是因为,可以,但是,因为您想在此刻玩提取.如果您不想玩访存,则不要调用它.如果您需要在特定情况下玩访存,那么您就需要可以玩访存的东西.您可以通过接口声明来确保这一点.

The important point here being that when you call playFetch() on something, it's because you want to play fetch with that animal. You don't call playFetch because, well... you can, but because you want to play fetch in this very moment. If you don't want to play fetch, then you don't call it. If you need to play fetch in a certain situation, then you need something that can play fetch. You ensure this through interface declarations.

您可以使用类继承来实现相同的目的,但是灵活性较差.在某些情况下,虽然存在严格的层次结构,但非常有用:

You can achieve the same thing using class inheritance, it's just less flexible. In some situations where rigid hierarchies exist though it's perfectly useful:

abstract class Animal { }

abstract class Pet extends Animal { }

class Dog extends Pet {
    public function playFetch() { ... }
}

class GermanShepherd extends Dog {
    public function beAwesome() { ... }
}

然后,在某些特定的上下文中,您可能不需要任何可以做某事(接口)的对象,但是您正在专门寻找GermanShepherd,因为只有它才能很棒:

Then, in some specific context, you may not require any object that can do something (interface), but you are specifically looking for a GermanShepherd, because only it can be awesome:

protected function awesomeness(GermanShepherd $dog) {
    $dog->beAwesome();
}

也许将来您会制作出新的GermanShepherd品种,它们也很棒,但是extendGermanShepherd类.它们仍然可以使用awesomeness函数,就像使用接口一样.

Maybe down the road you'll make a new breed of GermanShepherds that are also awesome, but extend the GermanShepherd class. They'll still work with the awesomeness function, just like with interfaces.

您当然不应该做的是遍历一堆随机的东西,检查它们是什么,然后让它们做自己的事情.在任何情况下这都不是很明智.

What you certainly should not do is to loop through a bunch of random things, check what they are and make them do their own thing. That's just not very sensible in any context.

这篇关于通用多态性与PHP示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆