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 ?
  }
}
4

3 回答 3

8

在 PHP 中,您不能使用语言中可用的功能将对象从类型/类 A“转换”为 B。

但是,如果您的对象支持序列化,您可以通过使用序列化来做到这一点(通常普通的旧 PHP 对象确实支持序列化)。在序列化形式中,您更改对象的类并再次对其进行反序列化。然后A变成了B。但这并不是很流畅。

于 2011-08-19T15:12:26.170 回答
3

这实际上应该是一个评论,但我要提出一个重要的观点。

编程就是工程,编程就是设计。在不知道如何使用的情况下,无法说明为什么设计 A 比设计 B 更好。问一个设计师,你的提交按钮应该是红色还是绿色 - 她说:嗯,在哪里,在哪个网站上?询问工程师是否应该使用横梁或齿轮联轴器 - 答案将是:取决于用途。那么,是什么让你认为我们可以给你一个有意义的设计建议,如果你只给我们一个带有“foo”方法的“BrokenCar”类。告诉我们你真正想要达到的目标,否则我能想出的唯一答案是

使用 foo 的最佳方式是 bar

于 2011-08-19T15:22:07.300 回答
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 的所有子类中自动可用。

于 2011-08-19T15:39:21.133 回答