在抽象类方法中返回抽象类的子类

时间:2009-11-06 15:30:39

标签: php class inheritance polymorphism

我有一个类,它具有从数据库中检索子元素的功能。以下代码将是伪代码,因为我希望尽可能简单。

abstract class SomeHostObject extends SomeObject {

   function getChild($identifier) {
      global $database;
      $id = $database->select('Some MySQL Query');
      // that is the problem
      return ?new? ???($id);
   }

}

如您所见,班级SomeHostObject是抽象的,必须进行扩展。

问题是getChild()不应返回SomeHostObject实例(不仅因为它甚至无法实例化),而是扩展SomeHostObject的类的新实例。

例如,如果有一个扩展PageObject的类SomeHostObject,则函数getChild()应返回一个带有新ID的新PageObject实例。

我不知道是否要将这个问题称为'先进',但对我来说这是一个主要问题。

3 个答案:

答案 0 :(得分:4)

abstract class SomeHostObject extends SomeObject {

   function getChild($identifier) {
      global $database;
      $id = $database->select('Some MySQL Query');
      // that is the problem
      return $this->createObject($id);
   }
   abstract protected function createObject($id);

}

class PageObject extends SomeHostObject
{
  protected function createObject($id)
  {
    return new PageObject($id);
  }

}

答案 1 :(得分:2)

如果子对象与调用getChild()的对象是同一个类,你可以用这么简单的东西来完成它:

$class = get_class($this)

return new $class($id);

答案 2 :(得分:1)

嗯,如果这是一个好的软件设计或不是另一个讨论,超过2级继承闻到一点点imho。你应该考虑使用组合而不是继承。但是为了关注问题的技术部分,我会使用get_class来获取当前实例的类名并创建一个新的类名:

  <?php

  class SomeObject
  {}

  abstract class SomeHostObject extends SomeObject {
     function getChild($identifier) {
        $className = get_class($this);
        return new $className($identifier);
     }
  }

  class PageObject extends SomeHostObject
  {
    private $identifier;

    public function __construct($identifier = 0)
    {
      $this->identifier = $identifier;
    }
  }

  $instance = new PageObject();
  $child = $instance->getChild(10);

  print_r($child);

这会在我的机器上打印

PageObject Object ( [identifier:private] => 10 )