php中的trait
来源:互联网 发布:淘宝店模板收费吗 编辑:程序博客网 时间:2024/05/22 03:03
PHP5.4起,新增一种新的代码复用的方法,trait。PHP与JAVA类似,与C++不同,是一种单继承语言,PHP引入trait,可以减少单继承语言的限制,使开发人员能够自由地在不同的层次结构内独立的类中复用method。Trait和Class组合的语义定义了一种减少复杂性的方式,避免传统多继承和Mixin类相关经典问题,例如C++中的钻石危机(也称棱形问题):
优先级
指定alias会创建一个新的方法,原方法访问控制权限不变。不仅可以缩小权限的方向修改(public->private),也可以向放大权限的修改(private->public).
- 如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
- 如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。
Trait和Class相似,但仅仅旨在用细粒度和一致的方式来组合功能。无法通过trait自身来实例化。它为传统继承增加了水平特性的组合。
Trait使用case
<?phptrait Mytrait { public $a = 100; public function test1() { echo "Mytrait Test1\n"; } public static function test2() { echo "Mytrait Test2\n"; } }class TraitExample1 { use Mytrait;}$obj = new TraitExample1();$obj->test1();TraitExample1::test2();echo $obj->a . "\n";
优先级
对于方法:
当前类的成员>trait的方法>从基类继承的成员
对于变量:
当前类和基类中如果定义了trait同名的变量,如果该变量的定义兼容(同样的可见性及初始值)错误级别是E_STRICT,否则错误级别是E_ERROR.。
<?phptrait Mytrait { public $a = 100; public function test1() { echo "Mytrait Test1\n"; } public static function test2() { echo "Mytrait Test2\n"; } }class Base { public function test1() { echo "Base Test1\n"; } public static function test2() { echo "Base Test2\n"; } public static function test3() { echo "Base Test3\n"; } }class TraitExample1 extends Base{ use Mytrait; public function test1() { echo "TraitExample1 Test1\n"; } }$obj = new TraitExample1();$obj->test1();TraitExample1::test2();$obj->test3();echo $obj->a . "\n";
多个trait
通过逗号分隔,在use声明中列出多个trait,可以都插入到一个类中。
如果两个trait都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。为了解决多个trait在同一个类中的命名冲突,需要使用insteadof操作符来明确指定使用冲突方法中的哪一个。或者使用as操作符,可以将其中一个冲突的方法以另一个名称来引入。
同样的,如果两个trait有同名的变量,如果该变量的定义兼容(同样的可见性及初始值)错误级别是E_STRICT,否则错误级别是E_ERROR.
且不能通过解决方法冲突的方式解决。
<?phptrait Mytrait { public $a = 100; public function test1() { echo "Mytrait Test1\n"; } public static function test2() { echo "Mytrait Test2\n"; } }trait Mytrait2 { public function test1() { echo "Mytrait2 Test1\n"; } public static function test2() { echo "Mytrait2 Test2\n"; } }class TraitExample1{ use Mytrait,Mytrait2 { Mytrait::test1 insteadof Mytrait2; Mytrait2::test2 insteadof Mytrait; Mytrait::test2 as test2_2; } }$obj = new TraitExample1();$obj->test1();TraitExample1::test2();$obj->test2_2();echo $obj->a . "\n";
修改方法的访问控制
<?phptrait Mytrait { public function test1() { echo "Mytrait Test1\n"; } public function test2() { echo "Mytrait Test2\n"; } private function test3() { echo "Mytrait Test3\n"; } }class TraitExample1{ use Mytrait { test1 as protected; test2 as public test2_1; test3 as public; } }
指定alias会创建一个新的方法,原方法访问控制权限不变。不仅可以缩小权限的方向修改(public->private),也可以向放大权限的修改(private->public).
从trait来组成trait
与Class中使用多个trait类似,trait也可以使用多个trait。冲突的解决方式也一致。
<?phptrait Mytrait { public function test1() { echo "Mytrait Test1\n"; } public function test2() { echo "Mytrait Test2\n"; } }trait Mytrait2 { public function test1() { echo "Mytrait2 Test1\n"; } public function test2() { echo "Mytrait2 Test2\n"; } }trait Mytrait3 { use Mytrait, Mytrait2 { Mytrait::test1 insteadof Mytrait2; Mytrait2::test2 insteadof Mytrait; } }class TraitExample1{ use Mytrait3;}$obj = new TraitExample1();$obj->test1();$obj->test2();
Trait的抽象成员
为了对使用的类施加强制要求,trait支持抽象方法的使用。
Trait的静态成员
trait可以定义静态变量,静态方法。
<?phptrait Mytrait { public static $in = 10; public function test1() { echo "Mytrait Test1\n"; } public function test2() { echo "Mytrait Test2\n"; } }trait Mytrait2 { public function test1() { echo "Mytrait2 Test1\n"; } public static function test2() { echo "Mytrait2 Test2\n"; } }trait Mytrait3 { use Mytrait, Mytrait2 { Mytrait::test1 insteadof Mytrait2; Mytrait::test2 insteadof Mytrait2; Mytrait2::test2 as test3; } }class TraitExample1{ use Mytrait3;}$obj = new TraitExample1();$obj->test1();$obj->test2();TraitExample1::test3();[root@hadoop1 php]# cat trait2.php <?phptrait Mytrait { public static $in = 10; public function test1() { echo "Mytrait Test1\n"; } public function test2() { echo "Mytrait Test2\n"; }}trait Mytrait2 { public function test1() { echo "Mytrait2 Test1\n"; } public static function test2() { echo "Mytrait2 Test2\n"; }}trait Mytrait3 { use Mytrait, Mytrait2 { Mytrait::test1 insteadof Mytrait2; Mytrait::test2 insteadof Mytrait2; Mytrait2::test2 as test3; }}class TraitExample1{ use Mytrait3;}$obj = new TraitExample1();$obj->test1();$obj->test2();TraitExample1::test3();echo TraitExample1::$in;
0 0
- php中的trait
- php中的trait
- php中的trait
- php中的trait
- PHP中的trait方法冲突
- php中的Trait特性及作用
- PHP中的trait,interface和abstract
- PHP中的Trait 特性及作用
- php trait
- php trait
- PHP TRAIT
- PHP Trait
- PHP trait
- php trait
- PHP Trait
- php-Trait
- php trait
- php trait
- HDU 1203(dp46)
- [JAVA]从链表中删除重复数据(时间、空间)
- 小P的强力值
- HDOJ 1166 敌兵布阵(树状数组)
- HDU 2159(dp46)
- php中的trait
- Java 常量和变量
- C Primer Plus(第五版)中文版第11章编程练习(部分使用新特性,在codeblocks下通过测试,vc++6下运行可能出现错误)
- Linux系列之solr集群版环境搭建(六)
- 计算机网络
- java反射机制
- Python 解决 :NameError: name 'reload' is not defined 问题
- HDU 2577(dp46)
- TCP-上传图片