PHP是单承继的言语,正在PHP 5.4 Traits呈现以前,PHP的类无奈同时从两个基类承继属性或办法,为理解决这个成绩,php出了Trait这个特点。(Traits以及Go言语的组合性能有点相似)
用法:经过正在类中应用use要害字申明要组合的Trait称号,而详细某个Trait的申明应用trait要害词,Trait不克不及间接实例化。
<?php trait Drive { public $carName = 'BMW'; public function driving() { echo "driving {$this->carName}\n"; } } class Person { public function age() { echo "i am 18 years old\n"; } } class Student extends Person { use Drive; public function study() { echo "Learn to drive \n"; } } $student = new Student(); $student->study(); //输入:Learn to drive $student->age(); //输入:i am 18 years old $student->driving();//输入:driving BMW
论断:
Student类经过承继Person,有了age办法
经过组合Drive,有了driving办法以及属性carName。
假如Trait、基类以及本类中都存正在某个同名的属性或许办法,终极会保存哪个呢?经过上面的代码测试一下:
<?php trait Drive { public function hello() { echo "hello 周伯通\n"; } public function driving() { echo "周伯通没有会开车\n"; } } class Person { public function hello() { echo "hello 各人好\n"; } public function driving() { echo "各人城市开车\n"; } } class Student extends Person { use Drive;//trait 的办法笼罩了基类Person中的办法,以是Person中的hello 以及driving被笼罩 public function hello() { echo "hello 新学员\n";//当办法或属性同名时,以后类中的办法会笼罩 trait的 办法,以是此处hello会笼罩trait中的 hello } } $student = new Student(); $student->hello(); //输入:hello 新学员 $student->driving(); //输入:周伯通没有会开车
论断:当办法或属性同名时,以后类中的办法会笼罩 trait的 办法,而 trait 的办法又笼罩了基类中的办法。
假如要组合多个Trait,经过逗号分隔 Trait称号:
use Trait1, Trait2;
假如多个Trait中蕴含同名办法或许属性时,会怎么呢?谜底是当组合的多个Trait蕴含同名属性或许办法时,需求明白申明处理抵触,不然会孕育发生一个致命谬误。
<?php trait Trait1 { public function hello() { echo "Trait1::hello\n"; } public function hi() { echo "Trait1::hi\n"; } } trait Trait2 { public function hello() { echo "Trait2::hello\n"; } public function hi() { echo "Trait2::hi\n"; } } class Class1 { use Trait1, Trait2; } //输入:Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in
应用insteadof以及as操作符来处理抵触,insteadof是应用某个办法代替另外一个,而as是给办法取一个体名,详细用法请看代码:
<?php trait Trait1 { public function hello() { echo "Trait1::hello \n"; } public function hi() { echo "Trait1::hi \n"; } } trait Trait2 { public function hello() { echo "Trait2::hello\n"; } public function hi() { echo "Trait2::hi\n"; } } class Class1 { use Trait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; } } class Class2 { use Trait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; Trait2::hi as hei; Trait1::hello as hehe; } } $Obj1 = new Class1(); $Obj1->hello(); $Obj1->hi(); echo "\n"; $Obj2 = new Class2(); $Obj2->hello(); $Obj2->hi(); $Obj2->hei(); $Obj2->hehe();
输入
Trait2::hello Trait1::hi Trait2::hello Trait1::hi Trait2::hi Trait1::hello
<?php trait Hello { public function hello() { echo "hello,我是周伯通\n"; } } class Class1 { use Hello { hello as protected; } } class Class2 { use Hello { Hello::hello as private hi; } } $Obj1 = new Class1(); $Obj1->hello(); # 报致命谬误,由于hello办法被修正成受维护的 $Obj2 = new Class2(); $Obj2->hello(); # 输入: hello,我是周伯通,由于原来的hello办法依然是公共的 $Obj2->hi(); # 报致命谬误,由于别号hi办法被修正成公有的
Uncaught Error: Call to protected method Class1::hello() from context '' in D:\web\mytest\p.php:18
Trait 也能组合Trait,Trait中支持形象办法、动态属性及动态办法,测试代码以下:
<?php trait Hello { public function sayHello() { echo "Hello 我是周伯通\n"; } } trait World { use Hello; public function sayWorld() { echo "hello world\n"; } abstract public function getWorld(); public function inc() { static $c = 0; $c = $c + 1; echo "$c\n"; } public static function doSomething() { echo "Doing something\n"; } } class HelloWorld { use World; public function getWorld() { return 'do you get World ?'; } } $Obj = new HelloWorld(); $Obj->sayHello(); $Obj->sayWorld(); echo $Obj->getWorld() . "\n"; HelloWorld::doSomething(); $Obj->inc(); $Obj->inc();
输入
Hello 我是周伯通 hello world do you get World ? Doing something12
以上就是PHP中Trait的用法及示例的具体内容,更多请存眷资源魔其它相干文章!
标签: php开发教程 php开发资料 php开发自学 Trait
抱歉,评论功能暂时关闭!