「PHP の基本」ドキュメントを整理しているときに、見慣れない trait メソッドを見つけたので、今朝 2 時間かけて、trait メソッドのいくつかの機能と使用法を確認し、テストしました。それをまとめてこのブログに掲載しました。
Trait は PHP5.4 の新機能であり、PHP 多重継承のソリューションです。たとえば、2 つの抽象クラスを同時に継承するのは非常に面倒です。Trait はこの問題を解決するように設計されています。
トレイトの簡単な使い方
トレイトは使用前に定義する必要があります、定義メソッドとクラス定義はほぼ同じです
trait first_trait {
function first_method() { /* Code Here */ }
function Second_method() { /* Code Here */ }
}
同時に、このトレイトをクラスで使用したい場合は、 use キーワードを使用する必要があります
class first_class {
// これに注意してください行、first_trait の使用を宣言します
use first_trait;
}
$obj = new first_class();// trait
からメソッドを実行 $obj->first_method(); // 有効
$obj->second_method( ); // 有効
クラス内で定義されたトレイトの使用を直接宣言でき、クラスがインスタンス化された後、直接呼び出すことができます。オブジェクト内のメソッドを呼び出して、トレイト内のメソッドを呼び出します。クラスの継承は単一ですが、特性の使用は単一ではないため、これにより拡張性が大幅に向上することは間違いありません。
1 つの クラス で複数の トレイト
を使用する同じクラス内で使用でき、複数の特性はカンマで区切られます。
例:
trait first_trait
{
function first_method() { echo "method1"; }
}
trait Second_trait {
function Second_method ( ) { echo "method2"; }
}
class first_class {
// 複数のトレイトを使用中
use first_trait, Second_trait;
}
$obj= new first_class ( );
// 有効
$obj->first_method() // 印刷 : method1
// 有効
$obj->next_method(); : method2
Trait Conflict
複数の Trait を同時に使用すると、必然的に競合が発生します。たとえば、両方の特性が同じ名前のメソッドを挿入すると、競合が明示的に解決されない場合に致命的なエラーが発生します。
同じクラス内の複数の特性の名前の競合を解決するには、キーワードの代わりに、
を使用して、使用する競合メソッドを明確に指定します。 as 操作 このシンボルは、名前を変更し、競合するメソッドを導入するために使用されます。
trait first_trait {
function first_function() {
echo "最初の特性から";
}
}
trait Second_trait {
// ここ名前は first_trait と同じです。競合が発生します。
function first_function() {
echo "From Second Trait";
}
}
class first_class {
use first_trait , Second_trait {
// ここで
の代わりに first_trait の first_function を宣言します // Second_trait の代わりに First_trait::first_function;
Second_trait::first_function を Second_trait; として宣言します。 🎜> }
Trait で抽象メソッドを宣言できます。それを使用するクラスはそれを実装する必要があります。 trait first_trait { function first_method() { echo "method1"; }
abstract public function Second_method();// 呼び出しクラスが実装する必要があることを示す修飾子をここに追加できます。 🎜> }class first_method {
use first_trait; function Second_method() {
/* コードはここにあります */
}
}
Trait
Priority
PHP マニュアルには次のように書かれています: 優先順位は、現在のクラスのメソッドがトレイトのメソッドをオーバーライドすることです。トレイトは継承されたメソッドのメソッドをオーバーライドします。 つまり、優先度: 現在のクラスのメソッド > 特性メソッド > 継承されたメソッド。 同じ名前のメソッドが異なる優先度で定義されている場合、優先度の高いメソッドが優先度の低いメソッドを上書きします。
同じ名前の場合、2 つの特性が同じ優先度に属します。このメソッドが表示されると、致命的なエラーが報告されます。詳細については上記を参照してください。
class Base {
public functionsayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public functionsayHello() {
parent ::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld( );
$o->sayHello();
結果は次のように出力されます:
Hello World!
Traitアクセス許可制御
クラスと同様に、特性メソッドを定義するときに、そのアクセス許可 (public、protected、private) を指定することもできます。
public functionsayHello() {
echo 'Hello World!';
}
}
// SayHello アクセスを変更control
class MyClass1 {
use HelloWorld {sayHello as protected; }
}
// アクセス制御を変更するエイリアスをメソッドに与えます
// 元のsayHello のアクセス制御は変更
class MyClass2 {
use HelloWorld {sayHello as private myPrivateHello }
Trait が トレイトを使用すると、異なるトレイトを組み合わせて新しいトレイトを作成できるため、コードの再利用率が高くなります。もちろん、プログラム設計の要件も高くなります。
trait Hello {
public function SayHello() {
echo 'Hello ';
}}
trait World {
public function SayWorld() {
echo 'World!';
}}
特性 HelloWorld {
Hello, World を使用;
}
クラス MyHelloWorld {
HelloWorld を使用;
}
$o = new MyHelloWorld();
$o->sayHello();
$o ->sayWorld();
//Hello World! を出力します
クラスと同様に、静的メンバーは静的メソッドと静的プロパティに分けられ、どちらも static キーワードで宣言されます。
trait Counter {
public function inc() {
static $c = 0;
$c = $c + 1;
echo "$cn";
}
}
trait StaticExample {
public static function doSomething() {
return 'Doing something';
属性で属性が定義されると、クラスのインスタンスはその属性に自身の属性と同様にアクセスできます。また、アクセス許可を設定することはできますが、インスタンス化することはできません...
トレイトが属性を定義する場合、そのクラスは同じ属性を定義できないことに注意してください。名前を指定しないと、エラーが生成されます。クラス内のプロパティの定義が特性内の定義と互換性がある (可視性と初期値が同じ) 場合、エラー レベルは E_STRICT であり、そうでない場合は致命的エラーです。
trait PropertiesTrait {
public $x = 1;
class PropertiesExample {
use PropertiesTrait;}
$example = new PropertiesExample;
$example->x;
注意が必要な点
以上がTraitの基本的な使い方です。詳しくは公式マニュアルをご覧ください。
ここで注意すべき点がいくつかあります:
- 特性は、呼び出し側クラスによって継承された親クラスのメソッドをオーバーライドします
- クラスのような new を使用して特性をインスタンス化することはできません
- 単一の特性は複数の特性で構成できます
- 単一のクラスで複数の特性を使用できます
- 特性は、final、static、abstract などの修飾子をサポートします
- 特性間の競合を解決するために、代わりに演算子と as 演算子を使用できます
K 文献を参照してください
- http://php.net/manual/zh/ language.oop5.traits.php
- https://www.doubear .com/ Article/raityongfaxuexibiji.html
- http://www.kuqin.com/web/20111119/315048.html
- http://www.jb51.net/article /61260。 htm
最後に
私の個人 WeChat "Hua Weijun" をフォローして、私と一緒に PHP を学び、議論してください。私たちは一緒に歩きますテクノロジーの巨人への道を歩みます!