我认为目前实现你想要的唯一方法是:
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 中处理特性的一年多经验,我的建议是:尽量避免在特性中编写构造函数,或者如果必须这样做,至少使它们不包含参数。将它们放在特性中与构造函数的一般思想相违背,即:构造函数应该是特定于所属类的。其他进化较高的高级语言甚至不支持隐式构造函数继承。这是因为构造函数比其他方法有更强的与类的关系。事实上,它们的关系非常强,以至于甚至LSP也不适用于它们。Scala 语言中的特性(Java 的一个非常成熟且符合 SOLID 原则的后继者),不能具有带参数的构造函数。
编辑1:
PHP 5.4.11 中存在一个错误,实际上允许别名化超类方法。但这被 PHP 开发人员认为是不好的,因此我们仍然被困在我上面提出的繁琐解决方案中。但是该错误引发了有关如何处理此问题的讨论,我希望它将在未来的版本中得到解决。
与此同时,我一遍又一遍地遇到同样的问题。随着参数数量和 docblock 的行数重复多次使用特性而愤怒程度呈指数级增长。因此,我想出了以下模式,以尽可能地遵循 DRY 原则:
不要像这样重复整个参数集:
trait SayWorld {
public function __construct($a, $b) {
echo (int)$c * ($a+$b);
}
}
class MyHelloWorld extends Base {
use SayWorld {
SayWorld::__construct as private __swConstruct;
}
public function __construct($a, $b, $c = 0)
{
$this->__swConstruct($a, $b);
}
}
我编写了一个类,很像 tuple(在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;
}
public function __construct(SayWorldConstructTuple $Tuple, $c = 0)
{
$this->__swConstruct($Tuple->a, $Tuple->b);
$this->c = $c;
}
}
注意:当元组构造函数参数更多,以及更多类使用元组时,此模式显然更为有用。
通过使用PHP的动态特性,它可以进一步实现自动化。