php trait 特性

2020-05-30  本文已影响0人  X1_blog

trait 特性总结 :

  1. 使用关键字 : use / as / insteadof
  2. 属性: 不允许在继承的 trait 或 class 中赋值父trait已定义的属性
  3. 允许在继承的 trait 或 class 中重写父trait已定义的方法
  4. 允许同时继承多个trait
  5. 继承多个trait并存在方法名冲突时, 需要手动指明继承哪个trait的方法(insteadof)
  6. 允许使用as修改访问控制
  7. 允许在trait中使用抽象方法
  8. trait可以定义静态成员, 静态方法; 使用和在类中定义一样
trait A{
    public $name = 'A';
    public function info(){
        echo "This is info from trait A\n";
    }
    public function fun1(){
        echo "This is fun1 from trait A\n";
    }
    public function count(){
        static $count= 0 ;
        $count ++;
        echo  $count ."\n";
    }
    public static function static_fun(){
        echo "static function from trait A";
    }
}

trait B{
    use A;
    // public $name = 'B';       Fatal error: 不要在继承的trait中定义相同的属性
    public $age = '18';
    public function info(){     # trait 可以继承另一个trait属性和方法
        echo "This is info from trait B\n";
    }
    public function fun2(){
        echo "This is fun2 from trait B\n";
    }

    public function acceptControl(){
        echo "This is acceptControl from trait B\n";
    }

    abstract public function getName();
}

trait B2{
    public $age = '18';
    public function info(){     # trait 可以继承另一个trait属性和方法
        echo "This is info from trait B\n";
    }
    public function fun2(){
        echo "This is fun2 from trait B\n";
    }
}

class C{
    use B{
        acceptControl as protected;
    }
    // public $age = '81';   Fatal error: 不要在继承的类中定义相同的属性
    public function info(){         # 允许在类中重写方法
        echo "This is info from class C\n";
    }

    public function index(){
        echo $this->name ."\n";
        echo $this->age ."\n";
    }

    public function getName(){
        echo "abstract function getName instantiation in class C\n";
    }
}

class D1{
    use A,B2{
        A::info insteadof B2;       # 继承的trait方法冲突需要手动指定方法, 否则 Fatal error
    }
    public function index()
    {
        echo $this->name;
    }
}

class D2{
    use A,B2{
        B2::info insteadof A;
    }
}


$b = new C();
$b->info();     # This is info from B
$b->index();    # A 18
$b->fun1();     # This is fun1 from A
$b->fun2();     # This is fun2 from B
$b->getName();      # abstract function getName instantiation in C
// $b->acceptControl();     # 使用 as 修改访问控制为保护, 无法访问

$d1 = new D1();
$d2 = new D2();
$d1->info();     # This is info from trait A
$d2->info();     # This is info from trait B

$d1->count();     # 使用静态变量 : 1
$d1->count();     # 使用静态变量 : 2

$d2->count();     # 同样使用静态变量 : 1
$d2->count();     # 同样使用静态变量 : 2 , 不同实例之间不共享静态属性

$d1::static_fun();     # static function from trait A
上一篇下一篇

猜你喜欢

热点阅读