什么是PHP trait?

在PHP中,trait是一种代码复用机制,它用于解决 PHP 单继承的限制,我们可以理解为"代码片段",能够被多个类复用,是一种水平代码复用的方式。

为什么会有PHP trait?

PHP 5.4之前,一直都是单继承方式。比如我们有一个父类Base,一个子类Son,子类通过extends继承父类,通过PHP描述为:

<?php 
/* PHP 5.4之前只能单向继承 */
class Base{}//父类
class Son extends Base{}//子类只能继承一个父类
?>

而如果我们想要继承两个父类呢?

比如我们有两个父类Base1,Base2,一个子类Son,Son就不能同时继承Base1和Base2。

<?php 
/* PHP 5.4之前只能单向继承 */
class Base1{}//父类1
class Base2{}//父类2
class Son extends Base1,Base2{}//子类不能继承两个父类(报错!)
?>

因此,PHP出现了trait,它可以实现多段代码的复用。

怎么定义trait?

直接使用trait关键字。请读者切记,trait既不是类,也不是对象,更不是抽象类或者接口,而是一种代码复用机制

<?php 
trait TraitName {
    // 属性
    public $a;
    protected $b;
    private $c;
    
    // 方法
    public function f1() {
        // 方法实现
    }
    
    protected function f2() {
        // 受保护的方法
    }
    
    private function f3() {
        // 私有方法
    }
    
    // 抽象方法(要求使用类必须实现)
    abstract public function f4();
}
?>

怎么使用trait?

我们可以通过use关键字来使用trait。

<?php 
//1.先trait一段复用代码
trait copy_code {
    // 属性
    public $a;
    protected $b;
    private $c;
    
    // 方法
    public function f1() {
        // 方法实现
    }
    
    protected function f2() {
        // 受保护的方法
    }
    
    private function f3() {
        // 私有方法
    }
    
}
class Dotcpp_user
{
    //2. 使用关键字use使用trait
    use copy_code;
}
//3. 创建一个dotcpp_user用户
$dotcpp_user=new Dotcpp_user;
//4. 直接调用copy_code的属性和方法
$dotcpp_user->a;//使用copy_code里的属性
$dotcpp_user->f1();//使用copy_code里的方法
?>

知道如何声明和使用trait,回到最初的问题,如何实现类的多向继承?我们有两个trait,trait_base1,trait_base2,一个类son想要同时获得两者的全部属性和方法,我们可以通过“use trait_base1,trait_base2”来引入,然后直接使用:

<?php 
//1. 创建trait_base1
trait trait_base1
{
    public $a = 1;
    public function f() { echo '1'; }
}

//2. 创建trait_base2
trait trait_base2
{
    // 注意:避免属性名冲突,或使用不同属性名
    public $b = 2;
    public function f() { echo '2'; }
}

//3. Son类
class Son {
    use trait_base1, trait_base2 {
        // 只能解决方法冲突,不能解决属性冲突
        trait_base1::f insteadof trait_base2;  // 使用trait_base1的f方法
        trait_base2::f as f2;                  // 给trait_base2的f方法起别名f2
    }
}

//4. 测试
$son = new Son;
echo $son->a;      // 输出: 1
echo $son->b;      // 输出: 2(来自trait_base2的属性,没有冲突)
echo $son->f();    // 输出: 1
echo $son->f2();   // 输出: 2
?>

总结:通过trait,我们可以实现通用代码的水平复用,解决PHP中子类仅能单向继承的问题。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)