Php 如何解决子类中的方法重载(声明…应与兼容)?

Php 如何解决子类中的方法重载(声明…应与兼容)?,php,inheritance,static,warnings,overloading,Php,Inheritance,Static,Warnings,Overloading,该示例应能最好地证明这一点: class Generic { protected $a; protected $b; protected final function __construct($a,$b) { $this->a = $a; $this->b = $b; echo $this->a." ".$this->b; } public static function crea

该示例应能最好地证明这一点:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($a,$b);
    }


}

class Wanter extends Generic {
    public static function create($b) {
        return parent::create("I want",$b);
    }
}

Generic::foo("I need","coffee!");
Wanter::foo("coffee!");
预期产出:

I need coffee!I want coffee!
实际产量:

警告:Wanter::create($b)的声明应兼容 在第25行的[…]中使用Generic::create($a,$b)我需要咖啡!我要咖啡


很明显,这应该做什么(事实上)。不过,我当然希望在不发出警告的情况下运行它。如何在没有警告的情况下实现此功能?

这应该是显而易见的,但子方法定义必须与父方法定义匹配,因此缺少参数

我要做的是:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($b,$a); //reverse arguments
    }


}

class Wanter extends Generic {
    public static function create($a, $b="I want") {
        return parent::create($b,$a);
    }
}
请注意,我更改了参数的顺序,这样,具有默认值的参数就是第二个参数

您可以在子类中执行此操作,但如果顺序与父类不同,则可能会有点混乱

也就是说,在这种情况下,类似工厂方法的方法可能更合适

除了工厂模式之外,我不确定静态创建方法对您有多重要。当需要多态性之类的东西时,构造函数提供了更大的灵活性。例如,这样的事情是可以接受的

abstract class Generic {
   protected $a;
   protected $b;

   protected function create($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

}

class Wanter extends Generic {
    public function __construct($a) {
        return $this->create("I want",$a);
    }
}

然后,每个子级都可以定义自己的构造函数,并使用自己的一组必需参数。

公共静态函数create($a,$b)
子级方法缺少一个参数。是的,但这就是问题所在。该参数是不需要的,
create()。传统的方法重写不是您想要用于此类内容的模式。@很高兴知道这一点。另外一个原因是它应该是显而易见的。像这样的问题通常表明类结构使用了错误的模式。如果只是他,他们的构装师就不会有这么大的问题了