Traits は、コードの再利用を実現するために 5.4 で追加された新しいメソッドです。
php は単一の継承言語ですが、Java のようなコードの再利用を実現するために 1 つのクラスで複数の基本クラスを拡張することはできません。これにより、開発者は複数の基本クラスを異なるクラスで使用できるようになります。クラス。
トレイトとクラスは、コードの複雑さを軽減し、多重継承の問題を回避するために意味的に定義されています。
トレイトはクラスに似ていますが、統一されたきめ細かい方法で一連の関数を提供するためにのみ使用されます。トレイト内でインスタンス化することはできません。つまり、クラスのようなコンストラクター __construct() はありません。トレイトは PHP の従来の継承の拡張機能として機能し、水平統合を実装するため、アプリケーション クラスでは継承が必要なくなります。
1) 使い方
クラス内のトレイトを参照するには、キーワード「use」を使用します。複数の特性は「,」で区切られます。
コード例は次のとおりです:
<?php trait ezcReflectionReturnInfo { function getReturnType() { } function getReturnDescription() { } }class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?>
2) 優先度
基本クラスのメンバー関数は Traits の関数によってオーバーライドされ、現在のクラスのメンバー関数はその関数をオーバーライドします。特性で。
<?php class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo "World!\n"; } } class MyHelloWorld extends Base { use SayWorld; } class MyHelloWorldExt extends Base { use SayWorld; public function sayHello() { /** * 这里是5.4中的新的改动,5.4之前的版本会提示: * PHP Fatal error: Cannot use string offset as an array * 5.4中改进为返回字符串中的该索引号的字符 */ $str = "Arvin"; echo $str[0][0];// echo 'A'; } public function shortArray() { $array = ['first', 2, 3, 4];//5.4中的数组简单语法 echo $array[0];//5.4中的数组解引用取数组元素方法 } } $o = new MyHelloWorld(); $o->sayHello(); $oe = new MyHelloWorldExt(); $oe->sayHello(); echo "\n"; $oe->shortArray();
出力:
Hello World! A first
3) 複数の特性
複数の特性をクラスの宣言に追加でき、複数の特性は「,」で区切られます。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World'; } } class MyHelloWorld { use Hello, World; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
出力結果:
Hello World
4) Multiple Traits Conflict
同じクラスに追加された 2 つのトレイトが同じ関数名を持ち、明示的に処理されなかった場合、エラーが生成されます。
同じクラス内の Tratis 内の同じ名前を持つ 2 つの関数間の競合を解決するには、replaceof 演算子を使用して正しい関数を選択する必要があります。
メソッドの一意性と排他性により、内部競合を解決するために競合する関数の後に「as」演算子を使用することが許可されています。
<?php 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 A; A::bigTalk insteadof B; } } class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } } ?>
上記の例では、Talker はトレイト A とトレイト B を使用しているため、両方の同じ関数名の間に競合が発生します。
alker は、smallTalk がトレイト B から取得され、bigTalk がトレイト A から取得されると定義します。
Aliased_Talker は、as 演算子を使用して、トレイト B の bigTalk がエイリアス トークを通じて確実に実装されるようにします。
5) 関数のアクセス権限を変更する
Traits内の関数のアクセス権限属性を変更する構文として使用できます。
<?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } // Change visibility of sayHello,改变sayHello的访问权限。 class MyClass1 { use HelloWorld { sayHello as protected; } } // Alias method with changed visibility // sayHello visibility not changed,设置别名myPrivateHello。 class MyClass2 { use HelloWorld { sayHello as private myPrivateHello; } } ?>
6) 特性は新しい特性を形成します
多くのクラスと同様に、特性はクラスで使用でき、特性は特性で使用できます。 1 つのトレイトには 1 つ以上のトレイトを定義でき、これらのトレイトは他のトレイトの一部またはすべてのメンバーとして定義できます。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World!'; } } trait HelloWorld { use Hello, World; } class MyHelloWorld { use HelloWorld; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
上記のルーチンは出力します:
Hello World!
7) 抽象特性メンバー
クラス内の特定のメソッドを強制するために、特性で抽象メソッドを使用できます。
例:
<?php trait Hello { public function sayHelloWorld() { echo 'Hello '.$this->getWorld(); } abstract public function getWorld(); } class MyHelloWorld { private $world; use Hello; public function __construct($world) { $this->world = $world; } public function getWorld() { return $this->world; } } /** * 这里用到了5.4新功能 类实例化解引用操作 * (new class())->method(); */ (new MyHelloWorld('Arvin'))->sayHelloWorld(); ?>
この出力例:
Hello Arvin
8) 静的特性メンバー
静的静的変数は特性では定義できませんが、Tratis 関数では定義できます。 Tratis では静的関数も定義できます。
<?php trait Counter { public function inc() { static $c = 0;//静态变量 $c += 1; echo "$c\n"; } /** * 静态方法 */ public static function doSomething() { echo 'Doing something'; } } class C1 { use Counter; } (new C1())->inc(); // echo 1 C1::doSomething(); ?> 输出为: 1 Doing something
9) トレイトは属性を定義します
トレイトで属性が定義されている場合、そのクラスで定義されている属性が同じ属性を持つ場合、そのトレイトを参照するクラスに同じ名前の属性を定義することはできません。特性で定義された属性と同じ名前とアクセスの可視性、E_STRICT ヒント、そうでない場合は構文エラーがスローされます。
<?php trait PropertiesTrait { public $x = 1; public $y = 2; } class PropertiesExample { use PropertiesTrait; public $x = 1; //public $y = 3; } $example = new PropertiesExample; echo $example->x, $example->y; ?>
出力:
12
php5.4.0の新機能のいくつかを最後に変更ログに掲載します:
Added short array syntax support ([1,2,3]), see UPGRADING guide for full details. Added binary numbers format (0b001010). Added support for Class::{expr}() syntax. Added support for Traits.//本文的主要内容 Added closure $this support back. Added array dereferencing support.//数组解引用支持,上文中有实例 Added callable typehint. Added indirect method call through array. #47160. Added DTrace support.//传说DTrace是一个性能分析工具,可以跟踪出函数调用点,返回点等数据 Added class member access on instantiation (e.g. (new foo)->bar()) support.//类新实例解引用操作,上文中有实例
この記事は他の人に興味を持ってもらうことを目的としており、皆さんが引き続きphp5の新機能を探索してくれることを願っています。 4. ^_^