php 从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php 出了 Trait 这个特性
用法:通过在类中使用 use 关键字,声明要组合的 Trait 名称,具体的 Trait 的声明使用 Trait 关键词,Trait 不能实例化
如下代码实例:
<?php
trait Dog{
public $name="dog";
public function bark(){
echo "This is dog";
}
}
class Animal{
public function eat(){
echo "This is animal eat";
}
}
class Cat extends Animal{
use Dog;
public function drive(){
echo "This is cat drive";
}
}
$cat = new Cat();
$cat->drive();
echo "<br/>";
$cat->eat();
echo "<br/>";
$cat->bark();
?>
再测试 Trait、基类和本类对同名属性或方法的处理,如下代码
<?php
trait Dog{
public $name="dog";
public function drive(){
echo "This is dog drive";
}
public function eat(){
echo "This is dog eat";
}
}
class Animal{
public function drive(){
echo "This is animal drive";
}
public function eat(){
echo "This is animal eat";
}
}
class Cat extends Animal{
use Dog;
public function drive(){
echo "This is cat drive";
}
}
$cat = new Cat();
$cat->drive();
echo "<br/>";
$cat->eat();
?>
显示如下
所以:Trait 中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖 Trait 中同名的属性或方法
一个类可以组合多个 Trait,通过逗号相隔,如下
use trait1,trait2
当不同的 trait 中,却有着同名的方法或属性,会产生冲突,可以使用 insteadof 或 as 进行解决,insteadof 是进行替代,而 as 是给它取别名
如下实例:
<?php
trait trait1{
public function eat(){
echo "This is trait1 eat";
}
public function drive(){
echo "This is trait1 drive";
}
}
trait trait2{
public function eat(){
echo "This is trait2 eat";
}
public function drive(){
echo "This is trait2 drive";
}
}
class cat{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
}
}
class dog{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
trait2::eat as eaten;
trait2::drive as driven;
}
}
$cat = new cat();
$cat->eat();
echo "<br/>";
$cat->drive();
echo "<br/>";
echo "<br/>";
echo "<br/>";
$dog = new dog();
$dog->eat();
echo "<br/>";
$dog->drive();
echo "<br/>";
$dog->eaten();
echo "<br/>";
$dog->driven();
?>
<?php
trait Animal{
public function eat(){
echo "This is Animal eat";
}
}
class Dog{
use Animal{
eat as protected;
}
}
class Cat{
use Animal{
Animal::eat as private eaten;
}
}
$dog = new Dog();
$dog->eat();//报错,因为已经把 eat 改成了保护
$cat = new Cat();
$cat->eat();//正常运行,不会修改原先的访问控制
$cat->eaten();//报错,已经改成了私有的访问控制
?>
Trait 也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下
<?php
trait Cat{
public function eat(){
echo "This is Cat eat";
}
}
trait Dog{
use Cat;
public function drive(){
echo "This is Dog drive";
}
abstract public function getName();
public function test(){
static $num=0;
$num++;
echo $num;
}
public static function say(){
echo "This is Dog say";
}
}
class animal{
use Dog;
public function getName(){
echo "This is animal name";
}
}
$animal = new animal();
$animal->getName();
echo "<br/>";
$animal->eat();
echo "<br/>";
$animal->drive();
echo "<br/>";
$animal::say();
echo "<br/>";
$animal->test();
echo "<br/>";
$animal->test();
?>
以上就是对 trait 的总结,如有错误,还望指正哦!

![[小记]PHP之什么是Trait关键词?](/api/qr/qr.png?url=https://blog.kieng.cn/1218.html)
![[小记]PHP 之什么是 Trait 关键词? [小记]PHP 之什么是 Trait 关键词?](https://blog.kieng.cn/wp-content/uploads/2019/07/2019073003100634.png)
![[小记]PHP 之什么是 Trait 关键词? [小记]PHP 之什么是 Trait 关键词?](https://blog.kieng.cn/wp-content/uploads/2019/07/2019073003110761.png)
![[小记]PHP 之什么是 Trait 关键词? [小记]PHP 之什么是 Trait 关键词?](https://blog.kieng.cn/wp-content/uploads/2019/07/2019073003115050.png)
![[小记]PHP 之什么是 Trait 关键词? [小记]PHP 之什么是 Trait 关键词?](https://blog.kieng.cn/wp-content/uploads/2019/07/2019073003125281.png)
![[小记]PHP 之什么是 Trait 关键词? [小记]PHP 之什么是 Trait 关键词?](https://blog.kieng.cn/wp-content/uploads/2019/07/2019073003135110.png)






