在php 5中,我可以超载构造函数(以及其他任何方法)。但是,如果我得到这样的代码:
class Base {
public function __construct($a, $b) {
echo $a+$b;
}
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function __construct($a, $b, $c = 0) {
echo (int)$c * ($a+$b);
}
public function sayHello($a = null) {
parent::sayHello();
echo 'World!'.$a;
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld(2, 3);
$o->sayHello(1);
我有一个错误:
致命错误:myholyorld具有来自特征的碰撞构造函数定义我怎么可以修复它?您可以测试我的代码我现在认为做自己想做的唯一方法是:
class MyHelloWorld extends Base {
use SayWorld {
SayWorld::__construct as private __swConstruct;
}
public function __construct($a, $b, $c = 0)
{
$this->__swConstruct($a, $b, $c);
}
}
Edit2:
我的建议是基于PHP中处理特征的一年以上的建议,是:a aall特质中的vrate构造函数,或者如果您必须 - 至少使它们变得无参数。将它们保持在特征上是违反构造函数的想法,即:构造者应针对其属于的阶级的特定。其他,进化的高级语言甚至不支持隐式构造函数的继承。这是因为构造函数与其他方法的关系更强。实际上,它们具有很强的关系,以至于即使是
LSP也不适用于他们。 Scala语言的特征(Java的一个非常成熟和非常友好的继任者),没有一个带有参数的构造函数。
Edit1:
php 5.4.11中有一个链球,实际上允许别名超类方法。但这被PHP开发人员认为是禁止的,因此我们仍然坚持上面提出的那种麻烦的解决方案。但是,该错误提出了有关对此可以做什么的讨论,我希望它将在以后的发行中成为目标。
mean,而我一遍又一遍地遇到了同样的问题。我的刺激随着参数和图案线的数量呈指数升高,必须重复多次以使用该性状。因此,我想出了以下模式,以尽可能地遵守干燥规则:
重复此类参数集的目的:
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);
}
}
我写一个类似于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;
}
/**
* 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的动态性质可以进一步自动化。
try:
use SayWorld {
Base::__construct insteadof SayWorld;
}
帖子,但如果这对任何人有所帮助:我的情况类似,但决定使用一种略有不同的方法。我正在编写WordPress插件,并想传递插件信息(版本,名称,文本域等),但不想在重构或扩展另一个类时更改每个文件,因此我用constructor创建了一个性状这只是调用针对类特定操作的初始化功能。
trait HasPluginInfoTrait{
public function __construct() {
$this->plugin_name = PLUGIN_NAME;
$this->version = PLUGIN_VERSION;
if ( method_exists( $this, 'init' ){
$this->init();
}
}
}
class SampleClass {
use HasPluginInfoTrait;
private function init(){
// Code specific to SampleClass
}
}
尚未回答:
5.6.4
/5.5.20
(2015年1月22日)固定。fix是升级PHP版本。
具有新类的特征:
Trait Constructor { public function __construct(...$args) { // ... parent::__construct(...$args); // ... } } $traitor = new class (/* ... */) extends Base { use Constructor; }
如果您看到另一个类是具体的,并且使用构造函数使用一个特征,那么行为的水平组成很有可能与班级的继承相撞,显然,如果该混凝土类已经具有构造函数,但尤其是如果特质的构造函数不在尖端。 如果某个特征属于那里,这仍然令人反感。但是,由于
始终仅在构造函数内部存在,因此上面的匿名新类示例显示了一个用法图案(临时$this
替换构造函数包装。)
new