什么是将对象转换为其子类的适当OO方法(协变返回类型)?

8

我有一个子类需要返回其父类返回类型的子类。我相信这被称为协变返回类型。我想知道从父类转换为子类的最简单方法。

class A {
}
class B extends A {
  function bar() {
  }
}

class Car {
  function foo() {
    return new A();
  }
}

class BrokenCar extends Car {
  function foo() {
    $a = parent::foo();
    //What is the cleanest way to convert $a to type B ?
  }
}
3个回答

8
在PHP中,你不能通过语言中的某个功能“转换”类型/类A的对象为B。然而,如果你的对象支持序列化(通常普通PHP对象都支持序列化),你可以利用序列化来实现。在序列化形式中,你可以改变对象的类,并再次反序列化它。这样,A就被转换成B了。但这并不是十分流畅的方法。

3

实际上这应该是一条注释,但我想指出一个重要的观点。

编程既是工程,又是设计。如果不知道它将如何使用,就无法告诉为什么设计A比设计B更好。问一个设计师,你的提交按钮应该是红色还是绿色 - 她会说:嗯,在哪个网站上?问一个工程师,你应该使用梁还是齿合连接器 - 答案将是:取决于用途。那么,如果你只给了我们一个“BrokenCar”类和一个“foo”方法,你怎么能认为我们可以给你一个有意义的设计建议呢?告诉我们你实际想要实现什么,否则我唯一能想到的答案就是

使用foo的最佳方式是bar


1
抱歉我的例子比较模糊,可能我试图将我的操作简化了。我的意思是要说明'B'提供了一些在'A'中不存在的额外方法。在我的实际代码中,'B'还覆盖了'A'中的一些方法。我可以复制被覆盖的方法中的逻辑,然后完全不调用父类的'foo'方法,但这样会有很多重复的代码。 - aw crud

2
正文:
hakre所述,PHP原生不支持将数据类型转换为用户定义的类型(据我所知)。
您可以在A类或B类中创建一个方法来实现这一点。例如:
class A
{
    public static function fromB( B $object )
    {
        /* your routine to convert an object of class B to an instance of class A */
    }

    /* or */

    public static function fromA( A $object )
    {
        /* your routine to convert any object that is a subclass of A to a concrete instance of class A */
    }
}

或者

class B
    extends A
{
    // this method could even be implemented in A already as well actually
    public function toA()
    {
        /* your routine to convert this object to an object of class A */
    }
}

在第一个示例中,第一个工厂方法可能存在问题,因为它要求A具有关于特定子类的具体知识。您需要确定在您的情况下是否需要这样做。也许您可以将其抽象化,使工厂方法接受从A继承的任何对象,就像第二个工厂方法一样。
在第二个示例中,B已经自动知道A,因为它继承了它。这可能更可取。但是仔细想想,这甚至已经可以在A中实现,这样该方法就已经在所有A的子类中自动可用了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接