我知道你可以通过在你的类中声明来覆盖trait
方法,我很想知道是否可以以同样的方式覆盖trait
属性。这样做安全吗?文档中没有这个说明,所以我不敢实现它。
根据文档:
来自基类的继承成员被Trait插入的成员覆盖。优先顺序是当前类中的成员覆盖Trait方法,然后是继承的方法。
我知道你可以通过在你的类中声明来覆盖trait
方法,我很想知道是否可以以同样的方式覆盖trait
属性。这样做安全吗?文档中没有这个说明,所以我不敢实现它。
根据文档:
来自基类的继承成员被Trait插入的成员覆盖。优先顺序是当前类中的成员覆盖Trait方法,然后是继承的方法。
在使用trait的类中,您无法覆盖trait的属性。但是,在扩展使用trait的类的类中,您可以覆盖trait的属性。例如:
trait ExampleTrait
{
protected $someProperty = 'foo';
}
abstract class ParentClass
{
use ExampleTrait;
}
class ChildClass extends ParentClass
{
protected $someProperty = 'bar';
}
我的解决方案是使用构造函数,例如:
trait ExampleTrait
{
protected $someProperty = 'foo';
}
class MyClass
{
use ExampleTrait;
public function __construct()
{
$this->someProperty = 'OtherValue';
}
}
__include()
来更改静态特性属性,并在访问类时在autoloader
内调用它。 - akinuriupdatable
作为替代解决方案。当该属性仅在trait的方法中需要时,我会使用它...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';
}
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;
}