假设我在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
的代码中的任何内容。
答案 0 :(得分:1)
那是因为你在工厂方法中对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;
或使用黑客自动执行此操作:
答案 1 :(得分:0)
在你的例子中:
<强>问题强>
现在,这引起了我的注意:
class B extends A {
public static function factory() {
return parent::factory('constant');
}
}
短&amp;快速回答:
将其更改为:
class B extends A {
public static function factory() {
return A::factory('constant');
}
}
长期无聊的时髦延伸回答:
您正在尝试覆盖(并使用不同参数重载)静态函数。
这是一个常见的错误,假设静态方法是虚拟的,可以被覆盖。有些编程语言允许(Object Pascal,Delphi),其他编程语言(C#,Java),PHP依赖于版本,我认为。
老实说,“静态函数”的工作方式类似于具有命名空间的全局函数,它具有对类的所有成员的公共访问权限,而不是方法。我建议将它们视为全局函数。
干杯。