查看: 129|回复: 0

[tp6] Trait不是类也不是接口具体怎么使用

[复制链接]

748

主题

39

回帖

3907

积分

管理员

总舵主

积分
3907
QQ
发表于 2026-5-30 14:17:26 | 显示全部楼层 |阅读模式
Trait不是(抽象的和实质的)类也不是接口(interface),只是用来把公共代码打包提供给其他类使用。

由于php是单继承,即一个类只能有一个父类,所以Trait的作用就非常明显了,他可以让多个类共享使用公共的方法,绕过单继承的限制。
Trait里可以定义属性和方法,支持静态成员但不能定义常量。
1、静态成员,使用static修饰符修饰的属性和方法,例如:
a、静态属性(静态变量):
  1. static $name = '张三';
复制代码
b、静态方法:
  1. public static function sayHello()
  2. {
  3. echo 'Hello everyone!';
  4. }
复制代码


完整的Trait代码示例:
  1. trait MyTrait {
  2.     // ✅ 可以:静态属性(静态成员)
  3.     public static $staticVar = '我是静态属性';

  4.     // ✅ 可以:静态方法(静态成员)
  5.     public static function staticMethod() {
  6.         return '我是静态方法';
  7.     }

  8.     // ✅ 可以:普通方法
  9.     public function normalMethod() {
  10.         return '我是普通方法';
  11.     }

  12.     // ❌ 不可以:常量(原文说不能定义常量)
  13.     // const MY_CONST = 123;
  14. }
复制代码
使用这个Trait的类应该这样写:
  1. class Test {
  2.     use MyTrait;
  3. }

  4. // 静态成员直接用类调用,不需要 new 对象!
  5. echo Test::$staticVar;       // 输出:我是静态属性
  6. echo Test::staticMethod();   // 输出:我是静态方法
复制代码
在类的内部使用Trait定义的静态属性,可以这样写:
  1. trait MyTrait {
  2.     public static $staticVar = '我是静态变量';
  3. }

  4. class Test {
  5.     use MyTrait;

  6.     public function demo() {
  7.         // ✅ 正确:在类内部用 self::
  8.         echo self::$staticVar;
  9.     }

  10.     // 静态方法里也一样
  11.     public static function staticDemo() {
  12.         echo self::$staticVar;
  13.     }
  14. }
复制代码
在类的外部使用静态属性,就是类名::属性名或者方法名,例如:
  1. Test::$staticVar;
复制代码
在类的内部使用Trait定义的静态方法,使用self::方法,外部使用类名::方法,例如:
  1. trait MyTrait {
  2.     public static function traitStaticMethod() {
  3.         return "静态方法";
  4.     }
  5. }

  6. class Test {
  7.     use MyTrait;

  8.     public function demo() {
  9.         // 类内部:self::
  10.         echo self::traitStaticMethod();
  11.     }
  12. }

  13. // 类外部:类名::
  14. echo Test::traitStaticMethod();
复制代码
2、在类的内部使用非静态方法,则用$this->方法,内部使用非静态属性使用$this->属性名,在外部使用必须先new类,然后->,例如:
  1. trait MyTrait {
  2.     public function traitNormalMethod() {
  3.         return "普通方法";
  4.     }
  5. }

  6. class Test {
  7.     use MyTrait;

  8.     public function demo() {
  9.         // 内部必须用 $this->
  10.         echo $this->traitNormalMethod();
  11.     }
  12. }

  13. // 外部必须 new 成对象,再用 ->
  14. $obj = new Test();
  15. echo $obj->traitNormalMethod();
复制代码
总结终极记忆方法:
  1. 静态方法(static)
  2. 内部:self::
  3. 外部:类名::
  4. 普通方法(非 static)
  5. 内部:$this->
  6. 外部:对象 ->
复制代码
Trait可以定义抽象方法,必须使用abstract修饰,在使用Trait的类里必须实现Trait里定义的抽象方法。
道不同,不相为谋!理想要有,万一实现了呢?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注公众号

相关侵权、举报、投诉及建议等,请发 E-mail:2513533699@qq.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.|鲁ICP备19000917号|鲁公网安备37078302000320号

在本版发帖
关注公众号
QQ客服返回顶部