什么是特质
PHP 只允许单继承。换句话说,一个类只能改变另一个类。但是如果你需要包含一些不属于父类的东西呢?在 PHP 5.4 之前,你必须具有创造性,但在 5.4 中引入了特征。特征允许你基本上将一部分类复制并粘贴到主类中
trait Talk {
/** @var string */
public $phrase = 'Well Wilbur...';
public function speak() {
echo $this->phrase;
}
}
class MrEd extends Horse {
use Talk;
public function __construct() {
$this->speak();
}
public function setPhrase($phrase) {
$this->phrase = $phrase;
}
}
所以这里我们有 MrEd
,它已经扩展了 Horse
。但不是所有的马匹都是如此,所以我们有一个特点。让我们注意一下这是做什么的
首先,我们定义我们的特质。我们可以将它与自动加载和命名空间一起使用(另请参阅在命名空间中引用类或函数 )。然后我们将它包含在我们的 MrEd
类中,并使用关键字 use
。
你会注意到 MrEd
需要使用 Talk
函数和变量而不定义它们。还记得我们关于复制和粘贴的内容吗?这些函数和变量现在都在类中定义,就好像这个类定义了它们一样。
特征与抽象类最密切相关,因为你可以定义变量和函数。你也无法直接实例化 Trait(即 new Trait()
)。Traits 不能强制类隐式定义类似 Abstract 类或 Interface 的函数。特征仅用于显式定义(因为你可以根据需要使用多个接口,请参阅接口 )。
我什么时候应该使用特质?
在考虑特质时,你应该做的第一件事就是问自己这个重要的问题
我可以通过重构代码来避免使用 Trait 吗?
通常情况下,答案是肯定的。特征是由单一继承引起的边缘情况。滥用或过度使用特征的诱惑可能很高。但请考虑 Trait 为你的代码引入了另一个来源,这意味着还有另一层复杂性。在这里的例子中,我们只处理 3 个类。但 Traits 意味着你现在可以处理的远不止这些。对于每个特征,你的类变得更难以处理,因为你现在必须引用每个特征以找出它定义的内容(并且可能发生碰撞的位置,请参阅冲突解决 )。理想情况下,你应该尽可能少地保留代码中的 Traits。