PHP后期静态绑定(新静态):如何确保子类构造函数的兼容性并处理不同的构造函数?
对于一些更复杂的类层次结构,我用了一个简单的例子来说明这个问题 此类已给定-可以修改方法“createOrUpdate()”:PHP后期静态绑定(新静态):如何确保子类构造函数的兼容性并处理不同的构造函数?,php,inheritance,constructor,static,late-static-binding,Php,Inheritance,Constructor,Static,Late Static Binding,对于一些更复杂的类层次结构,我用了一个简单的例子来说明这个问题 此类已给定-可以修改方法“createOrUpdate()”: class A { protected $a; protected $b; protected $c; function __construct($a,$b,$c) { $this->a = $a; $this->b = $b; $this->c = $c; }
class A {
protected $a;
protected $b;
protected $c;
function __construct($a,$b,$c) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
public static function createOrUpdate($a,$b,$c) {
if(self::exists($b)) {
someWhateverUpdate();
} else {
new static($a,$b,$c);
}
}
}
现在让我们看看如果我们扩展它会发生什么:
class B extends A {
function __construct($a,$b,$c) {
parent::__construct($a,$b,$c);
}
}
B::createOrUpdate("rock","this","now");
很好
但是,如果有人执行createOrUpdate()参数$c,也可以正常工作
他默默地迷失了
错误:抛出ArgumentCountError
错误:工作正常,但行为完全出乎意料
现在我的问题是:我可以在
createOrUpdate()
中使用一些反射来检查当前调用的子类是否正确实现了构造函数吗?如果其他人可能在层次结构中实现更多的子类,您将如何处理此问题?如果您实现了到您的A类的接口,该如何处理
interface interfaceA {
public function __construct($a, $b, $c);
}
class A implements interfaceA
{
...
}
这将迫使每个扩展类要么没有构造函数,要么在类A上实现一个匹配的构造函数,要么PHP致命错误:B的声明::u构造($A,$B)必须与interfaceA兼容::u构造($A,$B,$c)
将被抛出
您还可以添加
公共静态函数createOrUpdate($a,$b,$c)对接口进行编码>以强制所有扩展类实现此类方法。在进一步试验@nforced的输入后,我找到了另一个好的解决方案-使构造函数受到保护并最终生效。现在,子类被强制实现一个使用所需构造函数的创建方法(例如,create()
)
class A {
protected $a;
protected $b;
protected $c;
protected final function __construct($a,$b,$c) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
public static function createOrUpdate($a,$b,$c) {
if(self::exists($b)) {
updateMe();
} else {
new static($a,$b,$c);
}
}
}
您是否尝试将对象/接口发送到upsert()
函数?
像这样:
类参数{
私家车$a;
私人股本(亿元);;
私人股本$c;
...
属性的setter和getter();
}
$paramObj=新参数();
$paramObj->setA('a');
...
D:upsert($paramObj);
类D扩展了{
公共静态函数upsert(参数$param){
如果($param->getA()){
doSth();
}否则{
$instance=newstatic();
$instance->a=$param->getB();
}
}
}
这只是我的一点看法,如果我错过了什么,请告诉我,谢谢 谢谢,我喜欢把界面放在层次结构之上的想法。如果可以忽略代码重用,那么将createOrUpdate抽象化也是一个好主意,但是在这种情况下我需要它。您还可以使用抽象公共静态函数createOrUpdate($a,$b,$c)执行抽象类a
强制子类实现此方法。
class E extends A {
function __construct($b,$c) {
$this->a = "Lorem";
$this->b = $b;
$this->c = $c;
}
}
D::createOrUpdate("rock","this","now");
interface interfaceA {
public function __construct($a, $b, $c);
}
class A implements interfaceA
{
...
}
class A {
protected $a;
protected $b;
protected $c;
protected final function __construct($a,$b,$c) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
public static function createOrUpdate($a,$b,$c) {
if(self::exists($b)) {
updateMe();
} else {
new static($a,$b,$c);
}
}
}