Open smilefish1987 opened 9 years ago
PHP 5.4 的新增特性可以参考 PHP手册,具体的特性列表如下:
namespace Name\TraitTest{ trait AddAndSub{ function add($a,$b){ return $a+$b; } function sub($a,$b){ return $a-$b; } function hello() { echo "trait hello()",PHP_EOL; } } class Base{ function hello(){ echo "Base hello()",PHP_EOL; } } class Test extends Base{ use AddAndSub; } class Smile extends Base{ use AddAndSub; function hello(){ echo "Smile hello()",PHP_EOL; } } // PHP Fatal error: Cannot instantiate trait Name\TraitTest\AddAndSub //$a = new AddAndSub(); $test = new Test(); echo $test->add(1,2),PHP_EOL; echo $test->sub(10,1),PHP_EOL; $smile = new Smile(); echo $smile->add(999,123),PHP_EOL; echo $smile->sub(1000,23),PHP_EOL; /* 从基类继承的成员被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的 方法,而 trait 则覆盖了被继承的方法 */ echo $test->hello(),PHP_EOL; echo $smile->hello(),PHP_EOL; // 多个 trait,通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中 trait Hello{ public function hello(){ echo "Hello",PHP_EOL; } } trait World{ public function world(){ echo "World",PHP_EOL; } } class HelloWorld{ use Hello,World; } $helloWorld = new HelloWorld(); $helloWorld->hello(); $helloWorld->world(); /* 如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。 为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用 冲突方法中的哪一个。 以上方式仅允许排除掉其它方法,as 操作符可以将其中一个冲突的方法以另一个名称来引入*/ trait A{ public function sayHello(){ echo "A",PHP_EOL; } } trait B{ public function sayHello(){ echo "B",PHP_EOL; } } class TestInsteadof{ use A,B{ B::sayHello insteadof A; } } $ti = new TestInsteadof(); $ti->sayHello(); class TestAlians{ use A,B{ A::sayHello insteadof B; B::sayHello as hello; } } $ta = new TestAlians(); $ta->sayHello(); $ta->hello(); //使用 as 语法还可以用来调整方法的访问控制 trait T1{ public function sayHello(){ echo "Hello,world!"; } } class Test1{ use T1{ sayHello as protected;} } class Test2{ use T1{ sayHello as private myPrivateHello;} } $test1 = new Test1(); //$test1->sayHello(); // 错误 $test2 = new Test2(); $test2->sayHello(); //$test2->myPrivateHello(); // 错误 /* 从 trait 来组成 trait,在 trait 定义时通过使用一个或多个 trait,它能够组合其它 trait 中的 部分 或全部成员 */ trait TraitHelloWorld{ use Hello,World; } class Test3{ use TraitHelloWorld; } $test3 = new Test3(); $test3->hello(); $test3->world(); // Trait 的抽象成员,为了对使用的类施加强制要求,trait 支持抽象方法的使用 trait TestAB{ public function hello(){ echo "hello",PHP_EOL; } abstract public function test(); } class MyTestAB{ use TestAB; public function test(){ echo "just test",PHP_EOL; } } $myTestab = new MyTestAB(); $myTestab->hello(); $myTestab->test(); //Trait 的静态成员,Trait中可以定义静态方法,方法中还能定义静态变量 trait Counter{ public function inc(){ static $count = 0; $count++; echo $count,PHP_EOL; } public static function m(){ echo "just test in m method",PHP_EOL; } } class C1{ use Counter; } class C2{ use Counter; } $c = new C1(); $c->inc(); C1::m(); $c2 = new C2(); $c2->inc(); /*Trait中同样可以定义属性,如果 trait 定义了一个属性,那类将不能定义同样名称的属性, 否则会产生一个错误。如果该属性在类中的定义与在 trait 中的定义兼容(同样的可见性和 初始值) 则错误的级别是 E_STRICT,否则是一个致命错误 */ trait PropertyTrait{ public $data = 10; public static $m = 123; } class C3{ use PropertyTrait; } $c3 = new C3(); echo $c3->data,PHP_EOL; echo C3::$m,PHP_EOL; }
PHP 5.4 新增特性
PHP 5.4 的新增特性可以参考 PHP手册,具体的特性列表如下: