php使用关键字trait
php只能继承一个父类,但是,使用trait,类可以使用多个方法来实现想要做的事情,相当于实现多继承。
class Base{ public function sayHello(){ echo 'hello'; }}trait SayHello{ public function sayHello(){ //调用父类的方法 parent::sayHello(); echo 'world'; }}class MyHelloWorld extends Base{ use SayHello;}$o = new MyHelloWorld();$o->sayHello();//输出 hello world!
当trait
中的方法和类中的方法相同的时候,优先级的顺序是类中的方法会将trait
中的方法覆盖,eg:
trait HelloWorld { public function sayHello() { echo 'Hello World!'; }}class TheWorldIsNotEnough { use HelloWorld; public function sayHello() { echo 'Hello Universe!'; }}$o = new TheWorldIsNotEnough();$o->sayHello(); //此处输出 'Hello Universe!'
使用多个trait
trait Hello { public function sayHello() { echo 'Hello '; }}trait World { public function sayWorld() { echo 'World'; }}class MyHelloWorld { use Hello, World; public function sayExclamationMark() { echo '!'; }}$o = new MyHelloWorld();$o->sayHello();$o->sayWorld();$o->sayExclamationMark();//以上会输出HelloWorld!
如果两个trait
使用了同一个方法,没有明确解决会发生报错, 为了解决多个trait
在同一个类的命名冲突,需要使用insteadof
操作符明确指定使用冲突方法的哪一个,as
操作符可以将其中的一个冲突的方法以另一个名称来引入。
trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; }}trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; }}class Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; A::bigTalk insteadof SB; }}class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; }}$o = new Talker();$o->smallTalk();$o->bigTalk();$o-SB();
trait
来组成trait
trait Hello{ public function sayHello(){ echo 'Hello'; }}trait World{ public function sayWorld(){ echo 'world'; }}trait HelloWorld{ use Hello,World;}class my_hello{ use HelloWorld;}$a = new my_hello();$a->sayHello();$a->sayWorld();
trait
支持抽象方法的使用
trait Hello{ public function sayHelloWorld(){ echo 'Hello'.$this->getWorld(); } abstract public function getWorld();}class Myhello{ private $world; use Hello; public function getWorld(){ return $this->world; } public function setWorld($val){ $this->world = $val; }}$a = new Myhello();$a->setWorld('123');$a->sayHelloWorld();
可以定义变量和方法
trait StaticExample{ //可以定义变量 public $x = '100'; //可以定义方法 public static function doSomething(){ return 'do something'; }}class Example{ use StaticExample;}$e = new Example();echo $e->x;echo Example::doSomething();