7.9 Trait

trait 是PHP为类只能单继承而实现的代码复用机制。

trait 不能继承,也不能实现接口。

trait 不能有常量。

trait 不能实例化。

trait 中可以使用 trait

trait 中可以使用抽象方法。

trait 中通过 insteadof 来解决命名冲突,也可以使用 as 来设置别名和访问级别。

trait 中的优先级为 自己 > trait > 父类

trait 和类中如果有同名的属性,那么需要保证他们的访问级别和值相同才不会报错。

一个简单的 trait 例子

// trait
trait One{
    // 普通属性
    public $name = 'One';

    // 不能有常量

    // 静态属性
    static $desc = 'Hello One';

    // 普通方法
    public function say(){
        echo $this->name . ': 
'; echo static::$desc . '
'; } } // 类 class Foobar{ // 引入 trait,可以引入多个,用逗号分开 use One; // 构造函数 public function __construct(){ // 调用trait 中的函数 $this->say(); } } // 实例化 new Foobar();

当子类继承了父类,同时引入了 trait,三者中如果有同名的成员(属性、方法),那么优先级从大到小是 自己 > trait > 父类

// trait
trait One{
    public function fn(){
        echo "One::fn";
    }
}
// parent
class Two{
    public function fn(){
        echo "Two::fn";
    }
}
// class
class Foobar extends Two{
    use One;
    public function fn(){
        echo "Foobar::fn";
    }
}

// 实例化 输出:Foobar::fn
(new Foobar())->fn();

当一个类使用了多个trait时,难免会发生 trait 之间会有命名冲突的问题,如果不解决,会报错。

// trait
trait One{
    public function foo(){
        echo "One::foo 
"; } public function bar(){ echo "One::bar
"; } } trait Two{ public function foo(){ echo "Two::foo
"; } public function bar(){ echo "Two::bar
"; } } trait Three{ public function foo(){ echo "Three::foo
"; } public function bar(){ echo "Three::bar
"; } } // class class Four{ // 引入 trait use One, Two, Three { // 当 One 中的 foo方法 存在冲突时,排除掉 Two和Three 中的方法 One::foo insteadof Two, Three; // 当 Two 中的 bar方法 存在冲突时,排除掉 One和Three 中的方法 Two::bar insteadof One, Three; // 还一种方式是给方法起个别名 Three::foo as tf; } public function call(){ $this->foo(); $this->bar(); $this->tf(); } } // 实例化 (new Four())->call(); /* 最终输出 One::foo Two::bar Three::foo */

当一个 trait 中的方法访问级别较低时,可以通过 as 给它重新设置访问级别

// trait
trait One{
    // 我是私有的,只能在类中使用,无法通过实例访问
    private function say(){
        echo "private 
"; } } // 类 class Foobar{ use One { // 调整方法的访问控制级别 say as public; } } // 实例化 (new Foobar())->say();

可以给 trait 添加抽象方法来强制要求使用者必须做一些事。

// trait
trait One{
    public function fn1(){
        return $this;
    }
    // 我是抽象方法
    public abstract function fn2();
}

// 类
class Foobar{
    use One;
    // 必须要实现抽象方法
    public function fn2(){
        echo "hello world";
    }
}

// 实例化
(new Foobar())->fn1()->fn2();

你可能感兴趣的:(7.9 Trait)