PHP 什么是特质?

例子

PHP仅允许单继承。换句话说,一个班级只能extend有另一个班级。但是,如果您需要包括不属于父类的内容怎么办?在PHP 5.4之前,您必须具有创造力,但是在5.4中引入了Traits。特质允许您基本上将一个班级的一部分“复制并粘贴”到您的主班级中

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。但不是所有的马匹Talk,因此我们有一个特质。让我们注意这是在做什么

首先,我们定义我们的特质。我们可以将其与自动加载和命名空间一起使用(另请参见在命名空间中引用类或函数)。然后,将其MrEd与关键字一起包含在类中use。

您会注意到,无需定义它们MrEd就可以使用Talk函数和变量。还记得我们所说的复制和粘贴吗?这些函数和变量现在都在该类中定义,就好像该类已定义它们一样。

特性与Abstract类关系最密切,因为您可以定义变量和函数。您也不能直接实例化Trait(即)。特性不能强迫类隐式定义一个函数,如Abstract类或Interface可以。特性用于显式定义(因为您可以根据需要选择任意数量的接口,请参见接口)。new Trait()implement

我什么时候应该使用特质?

考虑特质时,您应该做的第一件事就是问自己这个重要的问题

我可以通过重组代码来避免使用Trait吗?

答案通常是肯定的。性状是由单一继承引起的边缘情况。滥用或过度使用性格的诱惑可能很高。但是请考虑,一个特质为您的代码引入了另一个来源,这意味着存在另一层复杂性。在这里的示例中,我们仅处理3个类。但是,特质意味着您现在所能处理的远远不止这些。对于每个特质,您的班级变得更加难以应对,因为您现在必须参考每个特质来找出其定义(以及可能发生碰撞的地方,请参阅冲突解决方法)。理想情况下,您应在代码中保留尽可能少的特征。