如何在php> =5.4

问题描述 投票:0回答:4

在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具有来自特征的碰撞构造函数定义

我怎么可以修复它?您可以测试我的代码

Herey。

我现在认为做自己想做的唯一方法是:
php traits
4个回答
161
投票
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;
}

ref:phpdocs

帖子,但如果这对任何人有所帮助:
我的情况类似,但决定使用一种略有不同的方法。我正在编写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 } }

尚未回答:

8
投票

致命错误:myholyorld具有来自特征的碰撞构造函数定义

我可以修复它? 这是一个已知的错误(

#65576

5
投票
)分别用

5.6.4

/

5.5.20

(2015年1月22日)固定。
fix是升级PHP版本。

0
投票
因此,几乎总是只适用于使用__ gonstructor()

具有新类的特征:

Trait Constructor { public function __construct(...$args) { // ... parent::__construct(...$args); // ... } } $traitor = new class (/* ... */) extends Base { use Constructor; }

如果您看到另一个类是具体的,并且使用构造函数使用一个特征,那么行为的水平组成很有可能与班级的继承相撞,显然,如果该混凝土类已经具有构造函数,但尤其是如果特质的构造函数不在尖端。 如果某个特征属于那里,这仍然令人反感。但是,由于$this

始终仅在构造函数内部存在,因此上面的匿名新类示例显示了一个用法图案(临时

new

替换构造函数包装。)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.