我知道你可以通过在课堂上声明来覆盖trait
方法,我很好奇是否有可能过度使用trait
属性同样的方式。这样做安全吗?它不在文档中,所以我对实现它犹豫不决。
来自文档
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.
答案 0 :(得分:33)
您无法覆盖使用特征的类中的特征属性。但是,您可以在扩展使用特征的类的类中覆盖特征的属性。例如:
trait ExampleTrait
{
protected $someProperty = 'foo';
}
abstract class ParentClass
{
use ExampleTrait;
}
class ChildClass extends ParentClass
{
protected $someProperty = 'bar';
}
答案 1 :(得分:8)
我的解决方案是使用构造函数,例如:
trait ExampleTrait
{
protected $someProperty = 'foo';
}
class MyClass
{
use ExampleTrait;
public function __construct()
{
$this->someProperty = 'OtherValue';
}
}
答案 2 :(得分:1)
一种替代解决方案,在这种情况下,使用属性updatable
。
仅在特征的方法中需要该属性时,我才使用它...
trait MyTrait
{
public function getUpdatableProperty()
{
return isset($this->my_trait_updatable) ?
$this->my_trait_updatable:
'default';
}
}
...并在类中使用特征。
class MyClass
{
use MyTrait;
/**
* If you need to override the default value, define it here...
*/
protected $my_trait_updatable = 'overridden';
}
答案 3 :(得分:-5)
您可以在类中声明trait
属性,但必须保持trait
中的相同定义。它不能被不同的定义所覆盖。因此,由于您已经可以从课程访问trait
属性,因此无需再次重新定义。认为trait
可用作复制粘贴代码。
<?php
trait FooTrait
{
protected $same = '123';
protected $mismatch = 'trait';
}
class FooClass
{
protected $same = '123';
// This override property produces:
// PHP Fatal error: FooClass and FooTrait define the same property
// ($mismatchValue) in the composition of FooClass. However, the definition
// differs and is considered incompatible
protected $mismatch = 'class';
use FooTrait;
}