特性及其在PHP中的应用
从PHP 5 . 4 . 0版本开始,PHP提供了一个新的代码重用概念,即Trait。Trait字面意思是“特征”和“特性”。我们可以理解,使用关键字“Trait”可以为PHP中的类添加新的特性。
熟悉面向对象的人都知道,软件开发中代码重用有两种方式:继承和多态。在PHP中,只能实现单一继承。特质避免了这一点。下面通过一个简单的例子进行对比说明。
1.遗传VS多态VS性状
现在有两个班:Publish.php和Answer.php。要向其中添加LOG函数,请记录类内的操作。有以下方案:
遗传多态性
1.1继任
图3360
代码结构如下:
//Log.php?phpClass Log { public function startLog(){//echo.}公共函数endLog() { //echo.} }//Publish.php?phpClass发布扩展日志{ }//Answer.php?PhpClass Answer扩展Log{}显示继承确实满足要求。但是这违反了面向对象的原则。但是,发布和应答以及日志等操作之间的关系不是子类和父类之间的关系。因此,不推荐。
1.2.多态性
图3360
实现代码:
//Log.php?phpInterface Log { public function startLog();公共函数endLog();}//Publish.php?phpClass Publish实现Log { public function startLog(){//todo :实现startLog()方法。}公共函数endLog() { //TODO:实现endLog()方法。} }//Answer.php?phpClass Answer实现Log { public function startLog(){//todo :实现startLog()方法。}公共函数endLog(){//todo :的日志记录操作实现endLog()方法。}}应该相同,因此发布和应答操作中的日志实现是相同的。显然,这违反了DRY(不要重复自己)的原则。因此,不建议这样实现。
1.3.特点
图3360
实现代码如下:
//Log.php?phptrait Log { public function startLog(){//echo.}公共函数endLog() { //echo.} }//Publish.php?发布{使用日志;} $ Publish=new Publish();$ publish-startLog();$ publish-endLog();//Answer.php?phpclass答案{使用日志;} $答案=新答案();$ answer-startLog();$ answer-endLog();可以看出,我们在不增加代码复杂度的情况下实现了代码重用。
1.4结论
虽然继承的方式也可以解决问题,但是它的思维违背了面向对象的原则,非常粗鲁;多态也是可行的,但是不符合软件开发中的DRY原则,增加了维护成本。Trait避免了上述缺点,相对优雅地实现了代码重用。
2.TRAIT的范围
知道了Trait的好处,我们还需要知道它实现中的规则,先说范围。这是一个很好的证明,实现代码如下:
?发布{使用日志;public function doPublish(){ $ this-public f();$ this-protectF();$ this-privateF();} } $ Publish=new Publish();$ publish-DoPublish();执行上述代码的输出结果如下:公共函数保护函数私有函数
可以发现,在引用的Trait类中,Trait的范围是可见的。可以理解,use关键字将特性的实现Copy复制到引用特性的类中。
3.特性中属性的优先级
说到优先级,一定要有比较参照对象。这里的引用对象指的是Trait的类及其父类。
下面的代码证明了Trait应用程序中属性的优先级:
?phptrait Log { public function public f(){ echo _ _ METHoD _ _ } .公共职能PHP _ EOL}受保护的函数ProteCf(){ echo _ _ METHoD _ _ .受保护的功能. PHP _ EOL} }类Question { PUblic function PUblic(){ echo _ _ METHoD _ _ .公共职能PHP _ EOL}受保护的函数ProteCf(){ echo _ _ METHoD _ _ .受保护的功能. PHP _ EOL} }类发布扩展了问题{使用日志;公共函数PurifF(){ echo _ _ METHoD _ _ .公共职能. PHP _ EOL}公共函数DoPublish(){ $ this-public f();$ this-protectF();} } $ Publish=new Publish();$ publish-DoPublish();上述代码的输出结果如下:公开:3360公开公共功能日志:保护受保护的功能:
通过上面的例子,可以总结出特点应用中的优先级如下:1.来自当前类的成员覆盖了特点的方法2 .特质覆盖了被继承的方法
类成员优先级为:当前类特点父类
4.代替和如同关键字
在一个类中,可以引用多个特质,如下:
?phptrait Log { public function startLog(){ echo _ _ METHoD _ _ } .公共职能PHP _ EOL}受保护的函数endLog() { echo __METHOD__ .受保护的功能. PHP _ EOL} }特质检查{公共函数参数Check($ parameters){//do某物} }类出版扩展了问题{使用日志,检查;公共函数doPublish($ para){ $ this-startLog();$ this-ParameterCheck($ para);$ this-endLog();}} 通过上面的方式,我们可以在一个类中引用多个特质。引用多个特点的时候,就容易出问题了,最常见的问题就是两个特点中如果出现了同名的属性或者方法该怎么办呢?这个时候就需要用到代替和如同这两个关键字了。请看如下实现代码:
?phpt rait Log { public function Parameter CheCk($ parameters){ echo _ _ METHoD _ _ } ."参数检查"。$参数PHP _ EOL}公共函数startLog() { echo __METHOD__ .公共职能. PHP _ EOL} } trait CheCk {公共函数Parameter CheCk($ parameters){ echo _ _ METHoD _ _ ."参数检查"。$参数PHP _ EOL}公共函数startLog() { echo __METHOD__ .公共职能. PHP _ EOL} }类发布{使用检查,日志{检查:参数检查代替日志;日志:开始日志而不是检查;检查:开始记录为csl}公共函数doPublish(){ $ this-startLog();$ this-ParAmeter CheCk(' ParAmeters ');$ this-csl();} } $ Publish=new Publish();$ publish-DoPublish();执行上述代码,输出结果如下:Log:startLog公共函数检查:3360参数检查参数检查参数检查:开始日志公共函数
就如字面意思一般,而不是关键字用前者取代了后者,作为关键字给被取代的方法起了一个别名。
在引用特点时,使用了使用关键字,使用关键字也用来引用命名空间。两者的区别在于,引用特点时是在班级内部使用的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
版权声明:特性及其在PHP中的应用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。