(1204)实例演示trait的功能,三大特性和优先级
trait 可以当作类,但是不能被实例化,所以严格来讲不是类,
trait 就是
引入一些新功能,对我们没有任何影响(命名冲突除外),我们引入 trait 的当前类的优先级大于使用 use 引入的优先级,所以 trait 的功能可以看作是一种拓展。 重写没有任何影响,不重写也可以直接调用 trait 内的功能。
- 重写没有任何影响
trait show{
public static function getName (){
return 'trait小明';
}
}
//父类
class One {
public static function getName (){
return 'One小明';
}
}
//子类
class Two extends One{
use show;
public static function getName (){
return 'Two小明';
}
}
echo Two::getName(); //Two小明
- 不重写也可以直接调用 trait 内的功能
trait show{
public static function getName (){
return 'trait小明';
}
}
//父类
class One {
public static function getName (){
return 'One小明';
}
}
//子类
class Two extends One{
use show;
}
echo Two::getName(); //trait小明
1.实例 解析 trait 新特性的功能;
- 特性一实现代码的复用
简单一点理解就是我们可以把公共的方法写到 trait 中,这样可以节省大量重复代码,有点类似于 js 的封装
trait Copy{
public static function getName(){
echo 'trait小明';
}
}
class CopyOne{
use Copy;
}
class CopyTwo extends CopyOne{
use Copy;
}
CopyTwo::getname(); //trait
- 特性二 实现功能多拓展, php 是单继承语言,多拓展这种特性极大的简化了我们撸代码的效率
trait FunOne{
public static function sayOne(){
echo 'hello 拓展One';
}
}
trait FunTwo{
public static function sayTwo(){
echo 'hello 拓展Two';
}
}
trait FunOneAndTwo{
use FunOne,FunTwo;
}
class WorkOne{
use FunOneAndTwo; //hello 拓展Two
}
WorkOne::sayTwo();
- 由于我们第二个特性实现拓展,那么势必会在多拓展的时候遇到方法重名的问题,也就是命名冲突,那么 php 提供了相应的 trait 中命名冲突的 解决方案
*如果命名冲突会爆出以下错误Trait method getName has not been applied, because there are collisions with other trait methods on reName in
这时候我们使用 trait 特性解决命名冲突问题
// 解决方案
trait reNameOne{
public static function getName(){
echo 'nameONE';
}
}
/**
*
*/
trait reNameTwo
{
public static function getName(){
echo 'nameTwo';
}
}
/**
* reNameOneAndTwo
*/
trait reNameOneAndTwo
{
use reNameOne,reNameTwo{
reNameTwo::getName as nameOne;
reNameOne::getName insteadOf reNameTwo; // 告诉引擎不要去reNameTwo中找getNmame,因为已经被替换了
}
}
class reName{
use reNameOneAndTwo;
}
reName::getName();
2.子类同名成员优先大于父类同名成员,如果子类,父类,trait 中存在同名方法的时候, 而 trait 在子类中调用,此时子类 > trait > 父类
// trait类
trait show{
// private static $name = 'trait小明';
public static function getName (){
return 'trait小明';
}
}
//父类
class One {
// private static $name = 'One小明';
public static function getName (){
return 'One小明';
}
}
//子类
class Two extends One{
use show;
// private static $name = 'Two小明';
public static function getName (){
return 'Two小明';
}
}
echo Two::getName(); //Two小明