PHP の学習 -- 新しい機能の特徴
PHP 5.4.0 以降、PHP は traits と呼ばれるコード再利用の方法を実装しています。
Traits は、PHP のような単一継承言語用に用意されたコード再利用メカニズムです。トレイトは、単一継承言語の制約を軽減し、開発者が異なる階層内の独立したクラスでメソッド セットを自由に再利用できるように設計されています。特性とクラス構成のセマンティクスは、複雑さを軽減し、従来の多重継承とミックスインに関連する典型的な問題を回避する方法を定義します。
Trait はクラスに似ていますが、きめ細かく一貫した方法で機能を組み合わせるようにのみ設計されています。特性を単独でインスタンス化することはできません。これは、従来の継承に水平機能の組み合わせを追加します。つまり、アプリケーション クラスのメンバーを継承する必要がありません。
特性の例
特性 ezcReflectionReturnInfo {
関数 getReturnType() { /*1*/ }
関数 getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
ezcReflectionReturnInfo を使用します;
/* ... */
}
クラス ezcReflectionFunction は ReflectionFunction を拡張します {
ezcReflectionReturnInfo を使用します;
/* ... */
}
?>
優先度
基本クラスから継承されたメンバーは、トレイトによって挿入されたメンバーによってオーバーライドされます。優先順位は、現在のクラスのメンバーがトレイトのメソッドをオーバーライドし、トレイトが継承されたメソッドをオーバーライドすることです。
優先順位付けの例
クラスベース{
パブリック関数 SayHello() {
「こんにちは」をエコーします;
}
}
特性 SayWorld {
パブリック関数 SayHello() {
親::sayHello();
「ワールド!」をエコー;
}
}
クラス MyHelloWorld は Base {
を拡張します
SayWorld を使用する;
}
$o = 新しい MyHelloWorld();
$o->sayHello();
?>
上記のルーチンは次のように出力します: Hello World!
基本クラスから継承されたメンバーは、挿入された SayWorld トレイトの SayHello メソッドによってオーバーライドされます。その動作は、MyHelloWorld クラスで定義されたメソッドと一致しています。優先順位としては、現在のクラスのメソッドが特性メソッドをオーバーライドし、特性メソッドが基本クラスのメソッドをオーバーライドします。
優先順位の別の例
特性 HelloWorld {
パブリック関数 SayHello() {
「Hello World!」をエコーします;
}
}
クラスTheWorldIsNotEnough {
HelloWorld を使用します;
パブリック関数 SayHello() {
「Hello Universe!」をエコーします;
}
}
$o = 新しいTheWorldIsNotEnough();
$o->sayHello();
?>
上記のルーチンは次のように出力します: Hello Universe!
複数の特性
カンマで区切って use ステートメントに複数の特性をリストすると、それらをクラスに挿入できます。
複数の特性の使用例
特性こんにちは{
パブリック関数 SayHello() {
「こんにちは」をエコーします;
}
}
特性ワールド{
パブリック関数 SayWorld() {
「ワールド」をエコー;
}
}
クラスMyHelloWorld {
Hello, World を使用します。
パブリック関数 SayExclamationMark() {
エコー '!';
}
}
$o = 新しい MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>
上記のルーチンは次のように出力します: Hello World!
紛争解決
2 つのトレイトが同じ名前のメソッドを挿入した場合、競合が明示的に解決されないと致命的なエラーが発生します。
同じクラス内の複数のトレイトの名前の競合を解決するには、 replaceof 演算子を使用して、競合するメソッドのどれを使用するかを明示的に指定する必要があります。
上記のメソッドでは、他のメソッドを除外することのみが可能です。as 演算子は、競合するメソッドの 1 つを別の名前で導入できます。
紛争解決の例
特性A {
パブリック関数 smallTalk() {
エコー 'a';
}
パブリック関数 bigTalk() {
「A」をエコー;
}
}
特性B{
パブリック関数 smallTalk() {
エコー 'b';
}
パブリック関数 bigTalk() {
エコー 'B';
}
}
クラストーカー{
A、B を使用する {
A の代わりに B::smallTalk を使用します。
B;
の代わりに A::bigTalk
}
}
クラス Aliased_Talker {
A、B を使用する {
A の代わりに B::smallTalk を使用します。
B;
の代わりに A::bigTalk
B::bigTalk をトークとして;
}
}
?>
この例では、トーカーは特性 A と B を使用します。 A と B は競合するメソッドを持っているため、トレイト B の smallTalk とトレイト A の bigTalk を使用することを定義します。
Aliased_Talker は、as 演算子を使用して、トークを B の bigTalk のエイリアスとして定義します。
メソッドのアクセス制御を変更する
as 構文を使用して、メソッドのアクセス制御を調整することもできます。
メソッドアクセス制御の変更例
特性 HelloWorld {
パブリック関数 SayHello() {
「Hello World!」をエコーします;
}
}
//sayHello
のアクセス制御を変更します
クラスMyClass1 {
HelloWorld {sayHello を保護として使用します。
}
//アクセス制御を変更するエイリアスをメソッドに与えます
//元のsayHelloのアクセス制御は変更されていません
クラスMyClass2 {
HelloWorld {sayHello をプライベート myPrivateHello として使用します
;
}
?>
特性から特性を構成する
クラスが特性を使用できるのと同じように、他の特性も特性を使用できます。特性を定義するときに 1 つ以上の特性を使用すると、他の特性の一部またはすべてのメンバーを組み合わせることができます。
特性から特性を形成する例
特性こんにちは{
パブリック関数 SayHello() {
「こんにちは」をエコーします;
}
}
特性ワールド{
パブリック関数 SayWorld() {
「ワールド!」をエコー;
}
}
特性 HelloWorld {
Hello, World を使用します。
}
クラスMyHelloWorld {
HelloWorld を使用します;
}
$o = 新しい MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>
上記のルーチンは次のように出力します: Hello World!
Traitの抽象メンバー
使用されるクラスに要件を強制するために、トレイトは抽象メソッドの使用をサポートします。
抽象メソッドを使用して要件を強制する例を示します
特性こんにちは{
パブリック関数 SayHelloWorld() {
echo 'Hello'.$this->getWorld();
}
抽象パブリック関数 getWorld();
}
クラスMyHelloWorld {
プライベート $world;
「こんにちは」を使用してください;
パブリック関数 getWorld() {
$ $ this> world;
}
パブリック関数 setWorld($val) {
$this->world = $val;
}
}
?>
Trait の静的メンバー
特性は静的メンバーと静的メソッドによって定義できます。
静的変数の例
特性カウンター{
パブリック関数 inc() {
静的 $c = 0;
$c = $c + 1;
"$cn" をエコー;
}
}
クラス C1 {
カウンターを使用する;
}
クラス C2 {
カウンターを使用する;
}
$o = new C1(); // エコー 1
;
$p = new C2(); // エコー 1
;
?>
静的メソッドの例
trait StaticExample {
パブリック静的関数 doSomething() {
return '何かをしています';
}
}
クラスの例 {
StaticExample を使用します;
}
例::doSomething();
?>
静的変数と静的メソッドの例
特性カウンター{
パブリック静的$c = 0;
パブリック静的関数 inc() {
self::$c = self::$c + 1;
echo self::$c . "n";
}
}
クラス C1 {
カウンターを使用する;
}
クラス C2 {
カウンターを使用する;
}
C1::inc(); // エコー 1
;
C2::inc(); // エコー 1
;
?>
プロパティ
Trait は属性を定義することもできます。
属性の定義例
特性プロパティTrait {
パブリック $x = 1;
}
クラスプロパティの例 {
PropertiesTrait を使用します;
}
$example = 新しいプロパティの例;
$example->x;
?>
トレイトがプロパティを定義する場合、クラスは同じ名前のプロパティを定義できません。定義しない場合はエラーが生成されます。クラス内のプロパティの定義が特性内の定義と互換性がある (可視性と初期値が同じ) 場合、エラー レベルは E_STRICT であり、そうでない場合は致命的エラーです。
競合の例
特性プロパティTrait {
public $same = true;
public $Difference = false;
}
クラスプロパティの例 {
PropertiesTrait を使用します;
public $same = true // 厳格な基準
;
public $ Different = true // 致命的なエラー
;
}
?>
使い方の違い
さまざまな使用例
名前空間 FooBar;
use FooTest; // FooTest を意味します - イニシャルはオプションです
?>
名前空間 FooBar;
クラス SomeClass {
use FooTest; // は FooBarFooTest を意味します
}
?>
最初の使用法は名前空間に FooTest を使用し、FooTest が見つかります。2 番目の使用法はトレイトを使用することで、FooBarFooTest が見つかります。
__CLASS__ と __TRAIT__
__CLASS__ は使用トレイトのクラス名を返し、__TRAIT__ はトレイト名を返します
特性 TestTrait {
パブリック関数 testMethod() {
"クラス: " . __CLASS__ .
「トレイト:」 . __TRAIT__ .
}
}
クラスBaseClass {
TestTrait を使用します;
}
クラス TestClass は BaseClass を拡張します {
}
$t = 新しい TestClass();
$t->testMethod();
//クラス: BaseClass
//特性: TestTrait
トレイトシングルトン
特性シングルトン {
/**
* プライベート構造体、通常はクラスを使用して定義されます
*/
//プライベート関数 __construct() {}
public static function getInstance() {
static $_instance = NULL;
$class = __CLASS__;
return $_instance ?: $_instance = new $class;
}
パブリック関数 __clone() {
trigger_error('「.__CLASS__.」のクローン作成は許可されていません。',E_USER_ERROR);
}
パブリック関数 __wakeup() {
trigger_error('「.__CLASS__.」のシリアル化解除は許可されていません。',E_USER_ERROR);
}
}
/**
* 使用例
*/
クラス foo {
シングルトンを使用します;
プライベート関数 __construct() {
$this->name = 'foo';
}
}
クラスバー{
シングルトンを使用します;
プライベート関数 __construct() {
$this->name = 'バー';
}
}
$foo = foo::getInstance();
echo $foo->name;
$bar = bar::getInstance();
echo $bar->名前;
调用特性方法
これは明白ではありませんが、果Traitのような方法は、一般的な種類の静的な方法として定義されており、使用することができます
实例以下
特性フー {
関数 bar() {
'baz' を返します。
}
}
echo Foo::bar(),"\n";
http://www.bkjia.com/PHPjc/927607.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/927607.html技術記事 PHP の特性 - トレイト PHP 5.4.0 以降の新しい特性で、PHP はトレイトと呼ばれる、PHP の継承言語に似たメソッドを実装しています。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
-
2024-10-22 09:46:29
-
2024-10-13 13:53:41
-
2024-10-12 12:15:51
-
2024-10-11 22:47:31
-
2024-10-11 19:36:51
-
2024-10-11 15:50:41
-
2024-10-11 15:07:41
-
2024-10-11 14:21:21
-
2024-10-11 12:59:11
-
2024-10-11 12:17:31