如何解决子类中的方法重载(...的声明应该兼容)?
How to solve method overloading in subclass (Declaration of ... should be compatible with )?
这个例子应该最能说明问题:
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!
实际输出:
Warning: Declaration of Wanter::create($b) should be compatible
with Generic::create($a, $b) in [...][...] on line 25 I need coffee!I want coffee!
很明显这应该做什么(就像它所做的那样)。但是我想 运行 这当然不会发出警告。如何在没有警告的情况下实施?
应该很明显,但是 child 方法定义必须与 parent 的方法定义相匹配,因此您缺少一个参数。
我会做的是:
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);
}
}
注意我改变了参数的顺序,这样默认的就是第二个参数。
您可以只在 child 中执行此操作,但可能会有些混乱,如果顺序与 parent class.
不同
也就是说,在这种情况下,工厂方法之类的东西可能更合适。
https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)
除了工厂模式之外,我不确定拥有静态 Create 方法对您来说有多重要。当需要诸如多态性之类的东西时,构造函数提供了更大的灵活性。例如这样的事情是可以接受的
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);
}
}
然后每个 child 都可以定义自己的构造函数,具有自己的一组必需参数。
这个例子应该最能说明问题:
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!
实际输出:
Warning: Declaration of Wanter::create($b) should be compatible with Generic::create($a, $b) in [...][...] on line 25 I need coffee!I want coffee!
很明显这应该做什么(就像它所做的那样)。但是我想 运行 这当然不会发出警告。如何在没有警告的情况下实施?
应该很明显,但是 child 方法定义必须与 parent 的方法定义相匹配,因此您缺少一个参数。
我会做的是:
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);
}
}
注意我改变了参数的顺序,这样默认的就是第二个参数。
您可以只在 child 中执行此操作,但可能会有些混乱,如果顺序与 parent class.
不同也就是说,在这种情况下,工厂方法之类的东西可能更合适。
https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)
除了工厂模式之外,我不确定拥有静态 Create 方法对您来说有多重要。当需要诸如多态性之类的东西时,构造函数提供了更大的灵活性。例如这样的事情是可以接受的
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);
}
}
然后每个 child 都可以定义自己的构造函数,具有自己的一组必需参数。