元のリンク: http://tabalt.net/blog/php-traits/
PHP は単一継承言語です。PHP 5.4 Traits が登場する前は、PHP クラスは 2 つの基本クラスからプロパティやメソッドを継承できませんでした。同時。 PHP の Trait の結合機能は Go 言語の結合機能と似ていますが、結合する Trait の名前はクラス内で use キーワードを使用して宣言されます。ただし、特定の Trait の宣言には trait キーワードが使用されません。直接インスタンス化されます。具体的な使用方法は以下のコードを参照してください:
<?php trait Drive { public $carName = 'trait'; public function driving() { echo "driving {$this->carName}\n"; } } class Person { public function eat() { echo "eat\n"; } } class Student extends Person { use Drive; public function study() { echo "study\n"; } } $student = new Student(); $student->study(); $student->eat(); $student->driving();出力結果は以下の通りです:
studyeatdriving trait上記の例では、Studentクラスはpersonを継承してeatメソッドを持ち、Driveを組み合わせることで駆動メソッドと属性を持ちます。車名。
Trait、基底クラス、このクラスに同名のプロパティやメソッドがあった場合、最終的にどちらが保持されるのでしょうか?次のコードでテストしてください:
<?php trait Drive { public function hello() { echo "hello drive\n"; } public function driving() { echo "driving from drive\n"; } } class Person { public function hello() { echo "hello person\n"; } public function driving() { echo "driving from person\n"; } } class Student extends Person { use Drive; public function hello() { echo "hello student\n"; } } $student = new Student(); $student->hello(); $student->driving();出力結果は次のとおりです:
hello studentdriving from driveしたがって、次のように結論付けることができます: メソッドまたは属性が同じ名前を持つ場合、現在のクラスのメソッドは特性のメソッドをオーバーライドし、特性のメソッドは、基本クラス Methods のメソッドをオーバーライドします。
複数のトレイトを組み合わせたい場合は、トレイト名をカンマで区切ります:
use Trait1, Trait2;複数のトレイトに同じ名前のメソッドまたはプロパティが含まれている場合はどうなりますか?その答えは、結合された複数の特性に同じ名前のプロパティまたはメソッドが含まれている場合、競合を解決するにはそれらを明示的に宣言する必要がある、そうしないと致命的なエラーが発生するということです。
<?phptrait Trait1 { public function hello() { echo "Trait1::hello\n"; } public function hi() { echo "Trait1::hi\n"; }}trait Trait2 { public function hello() { echo "Trait2::hello\n"; } public function hi() { echo "Trait2::hi\n"; }}class Class1 { use Trait1, Trait2;}出力結果は次のとおりです:
PHP Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in ~/php54/trait_3.php on line 20競合を解決するために、代わりに演算子と as を使用します。一方、as はメソッドにエイリアスを与えます。具体的な使用方法については、コードを参照してください。出力結果は次のとおりです。
<?phptrait Trait1 { public function hello() { echo "Trait1::hello\n"; } public function hi() { echo "Trait1::hi\n"; }}trait Trait2 { public function hello() { echo "Trait2::hello\n"; } public function hi() { echo "Trait2::hi\n"; }}class Class1 { use Trait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; }}class Class2 { use Trait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; Trait2::hi as hei; Trait1::hello as hehe; }}$Obj1 = new Class1();$Obj1->hello();$Obj1->hi();echo "\n";$Obj2 = new Class2();$Obj2->hello();$Obj2->hi();$Obj2->hei();$Obj2->hehe();as キーワードには、メソッドのアクセス制御を変更するための別の用途もあります。
Trait2::helloTrait1::hiTrait2::helloTrait1::hiTrait2::hiTrait1::helloTrait は、Trait と組み合わせることもできます。 Trait は、抽象メソッド、静的プロパティ、および静的メソッドをサポートします。コードは次のとおりです:
<?php trait Hello { public function hello() { echo "hello,trait\n"; } } class Class1 { use Hello { hello as protected; } } class Class2 { use Hello { Hello::hello as private hi; } } $Obj1 = new Class1(); $Obj1->hello(); # 报致命错误,因为hello方法被修改成受保护的 $Obj2 = new Class2(); $Obj2->hello(); # 原来的hello方法仍然是公共的 $Obj2->hi(); # 报致命错误,因为别名hi方法被修改成私有的出力結果は次のとおりです:
<?phptrait Hello { public function sayHello() { echo "Hello\n"; }}trait World { use Hello; public function sayWorld() { echo "World\n"; } abstract public function getWorld(); public function inc() { static $c = 0; $c = $c + 1; echo "$c\n"; } public static function doSomething() { echo "Doing something\n"; }}class HelloWorld { use World; public function getWorld() { return 'get World'; }}$Obj = new HelloWorld();$Obj->sayHello();$Obj->sayWorld();echo $Obj->getWorld() . "\n";HelloWorld::doSomething();$Obj->inc();$Obj->inc();元のリンク: http://tabalt.net/blog/php-traits/