繁体   English   中英

覆盖工厂方法:如何返回子类对象类型?

[英]Overriding of factory methods: how to return the child class object type?

假设我在PHP中有一个这样的父类:

class A {

    private $property;

    public static function factory($arg) {
        $object = new A();
        $object->property = $arg;
        return $object;
    }

}

我想以这种方式扩展它:

class B extends A {

    public static function factory() {
        return parent::factory('constant');
    }

}

当我执行B::factory()我得到一个类型为A的对象。 如果我想要B类型的对象怎么办? 我无法更改A类代码中的任何内容

第一版

那是因为您在工厂方法中对A类进行了硬编码。
A类中,尝试使用$object = new A()代替(要求PHP 5.3):

$class_name = get_called_class();
$object = new $class_name;

get_called_class() ”获取在其中调用静态方法的类的名称。

较短的版本:

$object = new static();

第二版(硬编码父类):

手动复制对象属性:

$parent = parent::factory($args);
$obj = new static();
$obj->setTimestamp($parent->getTimestamp());
$obj->setTimezone($parent->getTimezone());
return $obj;

或者使用骇客自动执行此操作:

如何在PHP中转换对象

在您的示例中:

  1. 您有两节课(至少)
  2. 这两个类都可以实例化(具体的,非纯的或抽象的)
  3. 一类是另一类的超类
  4. 这两个类都使用“工厂”方法实例化
  5. 子类的“ factory”方法可以调用超类的“ factory”方法
  6. 每个“工厂”方法可以具有几种类型或数量的参数

问题

现在,这引起了我的注意:

class B extends A {

    public static function factory() {
        return parent::factory('constant');
    }

}

简短答案:

更改为:

class B extends A {

    public static function factory() {
        return A::factory('constant');
    }

}

长期无聊的时髦扩展答案:

您正在尝试覆盖(并使用不同的参数重载)静态函数。

这是一个常见的错误,它假定静态方法是虚拟的,并且可以被覆盖。 我认为某些编程语言允许使用(Object Pascal,Delphi),其他不允许(C#,Java),PHP取决于版本。

老实说,“静态函数”的工作方式类似于带有命名空间的全局函数,它们具有对类的所有成员(而不是方法)的公共访问权。 我建议始终将它们视为全局功能。

干杯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM