Trait组合的同名方法的命名冲突的解决方案有哪些, 实例进行演示
演示如何在trait中改变trait成中的访问控制
代码部分
<?php
//1.先写2个trait,使2个trait中有又相同的方法aaa
trait Demo1
{
public function aaa()
{
return __TRAIT__ . '***' . __METHOD__;
}
}
trait Demo2
{
public function aaa()
{
return __TRAIT__ . '---' . __METHOD__;
}
protected function nnn()
{
return __TRAIT__ . '+++' . __METHOD__;
}
}
//1.替代,用Demo1中的aaa替换Demo2中的aaa
class Demo3
{
use Demo1, Demo2{
Demo1::aaa insteadof Demo2;
}
}
$demo = new Demo3;
echo $demo->aaa() , '<hr>';
//2.别名,把Demo2中的aaa取一个别名,客户端访问别名
//使用这种方法也必须用第一个Demo1中的aaa替代Demo2中的aaa,否则会出错
class Demo4
{
use Demo1, Demo2{
Demo1::aaa insteadof Demo2;
Demo2::aaa as bbb;
}
}
$demo = new Demo4;
echo $demo->bbb() , '<hr>';
//3.用as修改trait中成员的访问控制
//把Demo2种的受保护的aaa修改成为公共的的访问属性
//用use+as修改trait中的成员的访问控制的时候必须要修改发放的名称
class Demo5
{
use Demo2{
nnn as public vvv;
}
}
$demo = new Demo5;
echo $demo->vvv() , '<hr>';
总结
1、当use引用多个trait的时候,如果被引用的不同的trait中存在相同的方法名称,需要用insteadof进行替代,保留其中一个,如果被替代掉的方法也想使用,需要用as来修改被替代掉方法的别名
2、use+as不仅仅可以替换方法名称,而且可以修改该方法的访问控制,但是在修改该方法的访问控制的时候必须同时修改方法名称,修改后的方法名称不能与修改前的方法名称一致
实例演示一个trait与接口,抽象类联合编程
代码部分
<?php
//1.先建立一个接口
//先判断当天脚本中有没有要建立的接口名称,如果没有再建立
if (!interface_exists('iUser')){
interface iUser
{
public function user();
}
}
//2.再建立一个抽象类
if (!class_exists('user1')){
abstract class user1
{
abstract protected function name();
}
}
//3.再建立一个trait,并且在trait中实现以上接口和抽象类中的方法
if (!trait_exists('user2')){
trait user2
{
public function user()
{
return '我的名字是';
}
public function name()
{
return '程东旭';
}
}
}
//4.在建立一个实现类,并且use以上trait
if (!class_exists('user3')){
class user3
{
use user2;
}
}
$user = new user3();
echo $user->user() . $user->name();
总结
抽象类、接口和普通类混合使用可以简洁工作类中的代码,代码看起来更加优雅