我认为现在唯一的方法来做你想要的是:
class MyHelloWorld extends Base {
use SayWorld {
SayWorld::__construct as private __swConstruct;
}
public function __construct($a, $b, $c = 0)
{
$this->__swConstruct($a, $b, $c);
}
}
编辑2:
我的建议,基于超过一年处理PHP中的traits,是:避免在traits中编写构造函数,或者如果你必须 – 至少使它们无参数。让它们在特性上违背了构造函数的概念,即:构造函数应该具体到它们所属的类。其他,演进的高级语言甚至不支持隐式构造函数继承。这是因为构造函数比其他方法具有更强的关系。事实上,他们有这么强的关系,即使LSP不适用于他们。 Scala语言的特性(一个非常成熟和SOLID友好的Java继承者),can’t have a constructor with parameters。
编辑1:
在PHP 5.4.11中有一个bug,实际上允许别名超类方法。但是这被PHP开发人员认为是没有的,所以我们仍然坚持我上面提出的那个麻烦的解决方案。但是这个bug提出了一个关于这个可以做什么的讨论,我希望它将成为未来版本的目标。
同时我又一次遇到同样的问题。我的刺激随着docblock的参数和行的数量指数地增长,为了使用trait,它必须重复许多次。所以我想出了为了坚持DRY规则尽可能多的以下模式:
而不是像这样重复整套参数:
trait SayWorld {
/**
* This is a valid docblock.
*
* @param int $a Doc comment.
* @param int $b Doc comment.
*/
public function __construct($a, $b) {
echo (int)$c * ($a+$b);
}
}
class MyHelloWorld extends Base {
use SayWorld {
SayWorld::__construct as private __swConstruct;
}
/**
* Repeated and unnecessary docblock.
*
* @param int $a Doc comment.
* @param int $b Doc comment.
* @param int $c Doc comment.
*/
public function __construct($a, $b, $c = 0)
{
$this->__swConstruct($a, $b);
}
}
我写一个类很像一个元组(C#和Python用户熟悉的概念),并使用它而不是一个无尽的参数列表:
class SayWorldConstructTuple
{
public $a;
public $b;
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $b;
}
}
class MyHelloWorld extends Base {
use SayWorld {
SayWorld::__construct as private __swConstruct;
}
/**
* New and valid docblock.
*
* @param SayWorldConstructTuple $Tuple
* @param int $c Additional parameter.
*/
public function __construct(SayWorldConstructTuple $Tuple, $c = 0)
{
$this->__swConstruct($Tuple->a, $Tuple->b);
$this->c = $c;
}
}
注意:这个模式当然更有用的是更大量的元组的构造函数参数,更多的类使用元组。
它可以通过使用PHP的动态特性进一步自动化。