来自:mjsws > 馆藏分类
配色: 字号:
PHP5.4以后新增的trait功能使用介绍
2018-09-05 | 阅:  转:  |  分享 
  
PHP5.4以后新增的trait功能使用介绍trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公
共trait类,就像是装配汽车的配件,如果你的类中要用到这些配件,就直接用use导入就可以了,相当于把trait中的代码复制到当前
类中.因为trait不是类,所以不能有静态成员,类常量,当然也不可能被实例化。其实一个类中的代码,可以分为二大部分:一是我们自己写
的代码,暂且叫私有代码吧,还有一部分就是公共代码了,之前主要是由父类代码组成。现在你的类中的公共代码又多一个新成员:trait类代
码。如果说:继承可以纵向扩展一个类,那么trait就是横向扩展一个类功能下面以实例进行演示://1创建一个trait类Test1?
1234567891011121314151617181920212223242526he
llo1();//访问trait类Test1中的hello1()echo'''';echo$obj->name;//访问tt
rait类Test1中的$name属性echo'''';echo$obj->hello2();//访问ttrait类Test
1中的hello2()trait可以互相嵌套,一个trait类中可以用use导入另一个trait类,理解成代码复制就可以了.例如本
例中,在Test2中要用到Test1中的代码,我们只要改动二个地方就可以了。一是在Test2中用useTest1;导入Test1
中的代码,二是在Demo1类中的,去掉对Test1的引用,只保留对Test2的引用,想想这是为什么?给大家当作一个思考题吧~修改后
的代码如下://1创建一个trait类Test1?1234567891011121314151617181920212223242
526272829name;}}//3.创建Demo1类classDemo1{//
useTest1,Test2;useTest2;}//进行测试$obj=newDemo1;echo$obj->hel
lo1();//访问trait类Test1中的hello1()echo'''';echo$obj->name;//访问ttr
ait类Test1中的$name属性echo'''';echo$obj->hello2();//访问ttrait类Test1
中的hello2()刚才说过,类中导入的公共代码,除了trait方法集,还可以有父类,如果在子类中访问父类中的成员,大家应该很熟悉
了,现在一个类除了可以从父类继承成员,还可以从trait类中继承,那么有一个问题就不可避免了,如果父类和trait类中的成员命名冲
突怎么办?说人话,就是重名了怎么办?下面我们以方法重名来演示一下处理方案。再创建一个类Demo,做为Demo1类的父类。//3.创
建父类Demo?12345678classDemo{//在父类中创建一个与Test2重名的方法hello2()publicfu
nctionhello2(){return''父类Demo::hello2()'';}}代码如下:?123456789101112
13141516171819202122232425262728293031323334353637//1创建一个trait类Te
st1traitTest1{public$name=''PHP中文网'';//trait类中可以用属性publicfunc
tionhello1()//trait类中主要成员是方法{return''Test1::hello1()'';}}//2.创建t
riat类Test2traitTest2{useTest1;functionhello2(){//在Test2中访问Test
1中的属性name,注意语法与普通类是一样的return''Test2::hello2()''.$this->name;}}//3.
创建父类DemoclassDemo{publicfunctionhello2(){return''父类Demo::hello
2()'';}}//4.创建Demo1类classDemo1extendsDemo{//useTest1,Test2;u
seTest2;}//进行测试捕鱼游戏http://www.44771.net$obj=newDemo1;echo$o
bj->hello1();//访问trait类Test1中的hello1()echo'''';echo$obj->name;
//访问ttrait类Test1中的$name属性echo'''';echo$obj->hello2();//访问ttrai
t类Test1中的hello2()再次访问,会发现,结果与之前完全一样没有任何变化,父类Demo中的hello2方法好像隐身了,压
根不存在一样的。事实上,父类Demo中的hello2方法当然是存在的,只是被trat类Test2中的同名方法hello2覆盖掉了,
原因就是:trait类中的同名方法,访问优先级大于父类的同名方法。如果我们就想访问父类中的hello2方法,怎么办呢?只有一个办法
,要么父类方法改名,要么Test2中的方法改名,我们把Test2中的hello2方法改成hello3,再次访问,就可以看到父类的执
行结果了。那么,我们再进一点想一下,如果在子类也有一个hello2方法呢?那么结果会是什么样?我们来试一下,在Demo1类中添加如
下代码:?1234567891011//4.创建Demo1类classDemo1extendsDemo{//useTes
t1,Test2;useTest2;//在Demo1类中创建与Test2和父类Demo中同名的方法hello2()public
functionhello2(){return''Demo1::hello()'';}}在浏览器再次方法,果然不出所料,子类De
mo1中的hello2方法的执行结果覆盖掉了Test2中的同名方法现在我们总结一下在同一个类中,同名方法的优先级:子类>Trait
类>父类,与就是说,谁离调用者越近,谁的优先级就越高。下面我们再讨论最后一个问题:如果trait类中方法重名了,怎么办?如果是tr
ait类中被所有类共享的方法集,重名的可能性是非常大的。下面我们修改一下代码,删除一些用不到代码:?123456789101112
13141516171819202122232425262728293031//1创建一个trait类Test1traitTes
t1{publicfunctionhello(){return''Test1::hello()'';}}//2.创建triat类
Test2traitTest2{functionhello(){return''Test2::hello()'';}}//3.创
建类DemoclassDemo{useTest1,Test2{//用Test1中的hello()方法替代Test2中的同名方
法Test1::helloinsteadofTest2;//Test2中的hello()方法用别名访问Test2::helloastest2Hello;}//这里千万不要加分号;棋牌评测网http://www.77884.net}?//进行测试$obj=newDemo;echo$obj->hello();//访问Test1中的hello()echo'''';echo$obj->test2Hello();//别名访问Test2中的hello()
献花(0)
+1
(本文系mjsws首藏)