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

Php 在抽象类方法中返回抽象类的子类,php,class,inheritance,polymorphism,Php,Class,Inheritance,Polymorphism,我有一个类,它有一个从数据库中检索子元素的函数。下面的代码将是相当伪的,因为我想让它尽可能简单 abstract class SomeHostObject extends SomeObject { function getChild($identifier) { global $database; $id = $database->select('Some MySQL Query'); // that is the problem r

我有一个类,它有一个从数据库中检索子元素的函数。下面的代码将是相当伪的,因为我想让它尽可能简单

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
实例


我不知道该不该称这个问题为“高级”,但对我来说这是一个大问题。

Hm,如果这是一个好的软件设计与否是另一个讨论,那么两个以上的继承级别有点不合适。您应该考虑使用组合而不是继承。但为了关注问题的技术部分,我将使用get_类来获取当前实例的类名,并创建一个新实例,如下所示:

  <?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);

如果子对象与调用getChild()的对象是同一个类,那么您可以通过这样简单的方法来完成:


你想建一个工厂?只是查了一下。是的,它会像一个工厂。谢谢你介绍这个词!很好的方法,但我不认为这对性能有好处…无论如何,谢谢!见加布里埃尔1836的帖子评论。是的,我知道继承级别,但我真的需要它,因为它是用于可扩展CMS的。
PageObject Object ( [identifier:private] => 10 ) 
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);
  }

}
$class = get_class($this)

return new $class($id);