【问题标题】:Returning subclass of abstract class in abstract class method在抽象类方法中返回抽象类的子类
【发布时间】:2010-12-13 21:15:11
【问题描述】:

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

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 的类的新实例。

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

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

【问题讨论】:

标签: php class inheritance polymorphism


【解决方案1】:

嗯,如果这是否是好的软件设计是另一个讨论,那么 2 级以上的继承气味有点恕我直言。您应该考虑使用组合而不是继承。但是为了专注于问题的技术部分,我会使用 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 ) 

【讨论】:

  • 查看对 gabriel1836 帖子的评论。是的,我知道继承级别,但我真的需要它,因为它适用于可扩展的 CMS。
【解决方案2】:
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);
  }

}

【讨论】:

    【解决方案3】:

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

    $class = get_class($this)
    
    return new $class($id);
    

    【讨论】:

    • 不错的方法,但我不认为这对性能有好处……还是谢谢!
    猜你喜欢
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多