1. Introduction
Since PHP 5.4.0, PHP has implemented a code reuse method called trait.
Trait is a code reuse mechanism that is prepared for PHP-like single-inheritance languages. Trait to reduce the limitations of single-inheritance languages, developers are free to reuse method in separate classes within different hierarchies. The semantics of Trait and class combinations define a way to reduce complexity, avoiding traditional multi-inheritance and Mixin class-related typical problems.
Trait is similar to Class, but only designed to combine functionality in a fine-grained and consistent way. cannot be instantiated by trait itself. It adds a combination of horizontal features to the traditional inheritance, meaning that no inheritance is required between several classes of the application.
The class of trait cannot be instantiated;
1.2 Priority level
Members that inherit from the base class are overwritten by the members that are inserted by trait. Precedence is the method from which the member of the current class overrides the trait, and trait overrides the inherited method.
//base classclassbase{ Public functionSayHello () {Echo"Base Hello"; }}//Trait ClassTrait sayworld{ Public functionSayHello () {Echo"Trait Hello"; }}//classclassMyHelloextendsbase{ UseSayworld;}$obj=NewMyHello ();$obj->sayhello ();
Result: Trait Hello
More than 1.3 trait
Separated by commas, multiple trait are listed in the use declaration and can be inserted into a class.
//base classclassbase{ Public functionSayHello () {Echo"Base Hello"; }}//Trait ClassTrait sayworld{ Public functionSayHello () {Echo"Trait Hello"; }}trait world{ Public functionSayworld () {Echo' Trait World '; }}//classclassMyHelloextendsbase{ UseSayworld,World ; Public functionSayHello () {Echo"MyHello Hello"; }}$obj=NewMyHello ();$obj-SayHello ();Echo' <br/> ';$obj->sayworld ();
Results:
MyHello Hello
Trait World
The settlement of 1.4 trait conflict
If two trait all insert a method with the same name, a fatal error will occur if the conflict is not resolved explicitly.
In order to resolve the naming conflicts of multiple trait in the same class, it is necessary to use the insteadof operator to explicitly specify which of the conflicting methods to use.
The above method only allows the exclusion of other methods, and the as operator can introduce aliases for a method. Note that the as operator does not rename the method, nor does it affect its methods.
Example #5 Conflict Resolution
In this example, Talker uses trait A and B. Because A and B have conflicting methods, they define the use of smallTalk in trait B and the bigtalk in trait a.
Aliased_talker uses the as operator to define talk as an alias for the bigtalk of B
Trait a{ Public functionSmall () {EchoA; } Public functionbig () {EchoA; } Public functionmid () {Echo' Mid '; }}trait b{ Public functionSmall () {Echo' B '; } Public functionbig () {EchoB; }}classtalker{ UseAB {b:: Small insteadof A;//the small method uses the method in BA::Big Insteadof B; A::mid insteadof B; B:: Big asTalk ; }}$obj=NewTalker ();$obj->talk ();
1.5 access control for modified methods
Trait hello{ Public functionSayHello () {Echo' Hello '; }}classmyhello{ Usehello{SayHello as protected;//Modify access rights//SayHello as B//from individual name }}classmyclass{ Usehello{SayHello as PrivatePhello;//Modify an alias for access rights }}$obj=NewMyclass ();$obj->sayhello ();
1.6 from trait to form trait
Just as class can use trait, other trait can also use trait. Ability to combine some or all of the members of other trait by using one or more trait when trait defined
Trait hello{ Public functionsay () {Echo' Hello '; }}trait world{ Public functionSayworld () {Echo' World '; }}trait helloworld{ UseHello,World ;}classmyhelloworld{ UseHelloWorld;}$obj=NewMyhelloworld ();$obj->sayworld ();
Abstract members of the 1.7 trait
In order to impose mandatory requirements on the classes used, trait supports the use of abstract methods.
Trait hello{ Public functionsay () {Echo' Hello '; } Abstract Public functionget ();}classmyhelloworld{ UseHello; //the abstract method in trait must implement the Public functionget () {Echo"Hello World"; }}$obj=NewMyhelloworld ();$obj->say ();
1.8 Static Members
Trait counter{ Public $num= 1; Public functionInc () {Static $c= 0; $c++; Echo $c; $this->num = 2; } //Static Methods Public Static functionget () {Echo' Vic '; }}classc1{ UseCounter;}$obj=NewC1 ();$obj->inc ();//1$obj->inc ();//2C1::get ();//VicCounter::get ();//trait cannot be instantiated, but static methods can call$obj=NewC1 ();$obj->inc ();//3classc2{ UseCounter;}$obj=NewC2 ();$obj->inc ();//1Echo $obj->num;//2
1.9 Properties
Trait A property is defined, the class cannot define a property of the same name, otherwise it will produce fatal error. There is an exception: the property is compatible (same access visibility, initial default value).
Prior to PHP 7.0, the properties were compatible and there would be e_strict reminders.
trait propertiestrait { Public $same=true; Public $different=false;}classPropertiesexample { Usepropertiestrait; Public $same=true;//PHP 7.0.0 No problem, previous version is e_strict reminder Public $different=true;//Fatal error}
1.10 Trait Static
Trait counter{ Public $num= 1; Public functionInc () {Static $c= 0; $c++; Echo $c; $this->num = 2; } //Static Methods Public Static functionget () {return New Static();//is not a new trait, is the caller of new}}
Reference: http://php.net/manual/zh/language.oop5.traits.php
Https://www.cnblogs.com/CraryPrimitiveMan/p/4162738.html
PHP in trait