作用:解决代码复用问题,解决单一继承问题
Trait
和类相似,支持定义方法和属性
,但不是类,不支持定义构造函数
,因而不能实例化,只能被其他类使用,要在一个类中使用 Trait,可以通过use
关键字引入,然后就可以在类方法中直接使用 trait 中定义的方法了(Trait支持属性和方法以及可见性设置(private、protected、public),并且即使是 private 级别的方法和属性,依然可以在使用类中调用
)
与普通类的异同
-
相同点
trait 能够像普通的类一样定义属性,方法(包含抽象的、静态的) trait 引入到基类里面,其子类里面也能访问 trait 里面的属性和方法。
-
不用点
trait 不用实例化就能访问定义的普通方法以及属性。 trait 里面不能定义构造函数。
实践
<?php
Trait TraitOne {
public $propertyOne = 'argumentOne';
public function sayHello()
{
return 'My trait one';
}
}
Trait TraitTwo {
public function sayHello()
{
return 'My Trait Two';
}
}
class MyClass {
use TraitOne, TraitTwo {
TraitTwo::sayHello insteadof TraitOne; //指定要使用的trait
Traittwo::sayHello as twoSayHello; //同方法名的trait设置别名
}
public function traitMethodValue()
{
return $this->twoSayHello(); //调用trait别名方法
}
}
$myClass = new MyClass();
echo $myClass->twoSayHello();
class MyClassSon extends MYClass {
}
$myClass = new MyClassSon();
echo $myClass->twoSayHello(); //traits方法可以被继承
trait访问权限控制
trait Log{
public function save(){
return __METHOD__;
}
}
trait Comment{
public function save(){
return __METHOD__;
}
}
class Topic{
use Log,Commenr{
Log::save insteadof Comment; //当trait里面的方法重名时可用这种方式替换
Log::save as protect;//将此方法限制只能在本类进行使用
Comment::save as send; //如果非要使用Comment里面的save方法 可用别名方式替代
}
}
$topic=new Topic();
echo $topic->save();