开发者

What is the proper OO way to convert an object to one of its subclasses (covariant return type)?

I have a subclass that needs to return a subclass of the return type of its parent class. I believe this is called a covariant return type. I am wondering the simplest way to convert from the parent to the child class.

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 ?
  }
}
开发者_开发技巧


In PHP you can not "convert" objects from type/class A to B with a feature available in the language.

You can do so however by making use of serialization if your objects support it (normally plain old PHP objects do support serialization). In the serailized form you change the class of the object and unserialize it again. A has turned into B then. But that's not really fluent.


This actually should be a comment, but I'm going to make an important point.

Programming is engineering and programming is design. There's no way to tell why design A is better than design B without knowing how it's going to be used. Ask a designer, should your submit button be red or green - and she says: hmm, where, on which site? Ask an engineer if you should use a beam or a gear couping - and the answer will be: depends on what for. So, what makes you think we can give you a meaningful design advice, if you only gave us a "BrokenCar" class with a "foo" method. Tell us what you actually want to achieve with that, otherwise the only answer I can come up with is

the best way to use foo is bar


As hakre stated, casting to user defined types is not natively possible in PHP (as far as I know).

What you could do is create a method in either class A or B. Something like:

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 */
    }
}

or

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 */
    }
}

In the first example the first factory method can be problematic, since it requires A to have concrete knowledge about a specific subclass. You need to determine whether this is desirable in your situation. Perhaps you could abstract this to have the factory method accept any object that inherits from A, like the second factory method.

In the second example, B automatically already knows about A, because it inherits from it. This might be more desirable. But come to think of it, this could even already be implemented in A as well, such that the method is automatically available in all subclasses of A already.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜