PHP后期静态绑定(新静态):如何确保子类构造函数的兼容性并处理不同的构造函数?

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; }

对于一些更复杂的类层次结构,我用了一个简单的例子来说明这个问题

此类已给定-可以修改方法“createOrUpdate()”:

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