雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

PHP 代码复用机制 trait

2024-09-25 26

1. trait 的介绍2. trait 的基础用法3. trait 的优先级4. trait 的 as 用法5. 引入多个 trait 时的成员同名问题

1. trait 的介绍


众所周知,PHP 是单继承的语言,也就是 PHP 中的类只能继承一个父类,无法同时从多个基类中继承属性和方法,于是 PHP 实现了一种代码复用的方法,称之为 trait,使开发人员可以在不同层次结构内独立的类中复用属性和方法

trait 不是接口也不是类,不可以被实例化也不可以被继承,只是用来将公共代码(属性和方法)提供给其他类使用的

2. trait 的基础用法


trait 的成员:trait 的成员只能有属性和方法,不能定义类常量

// 定义一个 traittrait Say{    // 在 trait 中不能定义常量    // 报错提示:Traits cannot have constants    // const PI = 3.14; // 错误示例    // 属性    public static $name = 'liang';    // 方法    public static function hello()    {        echo 'Hello World !';    }}class User{    use Say; // 在类中引入 trait}// 测试输出echo User::$name;echo User::hello();

3. trait 的优先级


类成员和 trait 成员同名,属性和方法有不同的处理

如果是属性同名,PHP 直接抛出致命错误,方法同名则会有优先级之分

优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法

当前类成员 > trait 成员 > 继承的成员

4. trait 的 as 用法


trait User{    protected function hello()    {        echo 'user hello';    }}class Person{    use User {        # 起别名        hello as helloNewName;        # 起别名并且修改方法的访问控制        hello as public helloNewName;    }}$o = new Person;$o->helloNewName(); // user hello

5. 引入多个 trait 时的成员同名问题


引入多个 trait 时,如果存在成员同名,那么 PHP 会直接抛出致命错误

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个

也就是需要使用 insteadof 操作符指定使用哪个 trait 中的成员

trait User{    public function hello()    {        echo 'user hello <br>';    }}trait Admin{    public function hello()    {        echo 'admin hello <br>';    }}class Person{    use User, Admin {        // 指定 hello 方法应用哪个 trait 上的        Admin::hello insteadof User;        // User 上的 hello 想要使用的话就定义个别名,不想使用可以不定义别名        User::hello as helloUser;    }}$o = new Person;$o->hello();$o->helloUser();
更新于:23天前
赞一波!

文章评论

评论问答