PHP implements a code reuse method called trait.
Since PHP 5.4.0, PHP has implemented a code reuse method called trait.
Trait is a code reuse mechanism for a single inheritance language similar to PHP. Trait allows developers to freely reuse methods in independent classes in different hierarchies in order to reduce the restrictions of a single inheritance language.
Trait is a solution for PHP multi-inheritance. For example, it is very troublesome to inherit two Abstract classes at the same time. Trait is designed to solve this problem.
It adds a combination of horizontal features for traditional inheritance.
Example 1: Use the trait keyword to define the trait
trait first_trait{ public function hello(){ return 'hello'; }}
Example 2: use trait in the Class. use the use keyword. use commas to separate multiple trait entries.
trait first_trait{ public function hello(){ return 'hello'; }}trait second_trait{ public function world(){ return 'world'; }}class first_class{ use first_trait,second_trait;}$obj=new first_class();echo $obj->hello();echo $obj->world();
Example 3: Priority
Members inherited from the base class will be overwritten by the Members inserted by trait. The priority is that the members of the current class overwrite the trait method, while the trait method overwrites the inherited method.
Example: The member inherited from the base class will be overwritten by the member inserted by trait.
Class Base {public function sayHello () {echo 'hello' ;}} trait SayWorld {public function sayHello () {parent: sayHello (); echo 'World! ';}} Class MyHelloWorld extends Base {use SayWorld ;}$ o = new MyHelloWorld (); $ o-> sayHello (); // output result Hello World!
Example: The member of the current class overwrites the trait method.
Trait HelloWorld {public function sayHello () {echo 'Hello World! ';}} Class TheWorldIsNotEnough {use HelloWorld; public function sayHello () {echo 'Hello Universe! ';}}$ O = new TheWorldIsNotEnough (); $ o-> sayHello (); // output result Hello Universe!
Example 4: nesting between trait
Trait first_trait {public function hello () {echo 'hello' ;}} nested use first_trait between trait second_trait {// trait; public function world () {echo 'World' ;}} class first_class {use second_trait;} $ obj = new first_class (); echo $ obj-> hello (); echo $ obj-> world ();
Example 5: You can declare an abstract method in trait. The Class or trait must implement the abstract method.
Trait first_trait {public function hello () {echo 'hello';} // The abstract method public abstract function test ();} trait second_trait {// nested use first_trait between trait; public function world () {echo 'World';} // implement the test method public function test () {echo 'in first_trait '! ';}} Class first_class {use second_trait;} $ obj = new first_class (); echo $ obj-> hello (); echo $ obj-> world (); echo $ obj-> test (); // helloworld will be output!
Example 6: conflict resolution
If both trait inserts a method with the same name, a fatal error will occur if the conflict is not explicitly resolved.
To resolve naming conflicts between multiple trait nodes in the same class, you must useInsteadofOperator to specify which of the conflicting methods is used.
Only other methods can be excluded from the preceding method,AsThe operator can introduce one conflicting method with another name, which is equivalent to the alias of the method.
Trait A {public function smallTalk () {echo 'a';} public function bigTalk () {echo 'A' ;}} trait B {public function smallTalk () {echo 'B';} public function bigTalk () {echo 'B' ;}} class Talker {use A, B {B: smallTalk insteadof; // The smallTalk method of trait B will replace the smallTalk method A: bigTalk insteadof B of trait; // The bigTalk method of trait A will replace the bigTalk method of trait B} class Aliased_Talker {use A, B {B: smallTalk insteadof; // The smallTalk method of trait B will replace the smallTalk method A: bigTalk insteadof B; // The bigTalk method of trait A will replace the bigTalk Method B of trait B :: bigTalk as talk; // use the as operator to define the talk method as the alias of B's bigTalk method} $ obj = new Talker (); $ obj-> smallTalk (); $ obj-> bigTalk (); // The result will output bA $ obj2 = new Aliased_Talker (); $ obj2-> talk (); // B
Example 7: Modify method Access Control
Trait HelloWorld {public function sayHello () {echo 'Hello World! ';}} // Modify sayHello's access control class MyClass1 {use HelloWorld {sayHello as protected ;}} // give the method an access control alias that has changed the access control // The access control of the original sayHello does not change class MyClass2 {use HelloWorld {sayHello as private myPrivateHello ;}}
Example 8: Trait can also define attributes
trait PropertiesTrait { public $x = 1;}class PropertiesExample { use PropertiesTrait;}$example = new PropertiesExample;$example->x;
If trait defines an attribute, the class cannot define the attribute with the same name. Otherwise, an error occurs. If the definition of this attribute in the class is compatible with the definition in trait (the same visibility and initial value), the error level isE_STRICT
Otherwise, it is a fatal error.
Trait PropertiesTrait {public $ same = true; public $ different = false;} class PropertiesExample {use PropertiesTrait; public $ same = true; // Strict Standards public $ different = true; // fatal error}
If you have read this article, please try again. If there are any errors in this article, please note.
Learn from each other and make progress together!