trait 特性总结 :
- 使用关键字 : use / as / insteadof
- 属性: 不允许在继承的 trait 或 class 中赋值父trait已定义的属性
- 允许在继承的 trait 或 class 中重写父trait已定义的方法
- 允许同时继承多个trait
- 继承多个trait并存在方法名冲突时, 需要手动指明继承哪个trait的方法(insteadof)
- 允许使用as修改访问控制
- 允许在trait中使用抽象方法
- 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
网友评论