2012-04-07 9 views
20

なぜ私たちはPHPでクラスを持つ特性を拡張することができませんか?例えばPHPでクラスを持つ特性を拡張しますか?

Trait T { } 

Class C use T {} 
/* or */ 
Class C extends T {} 

な構文については、任意の潜在的な競合はありますか?そうは思わない。

+0

'クラスCはTを使用する方法{}'と異なることが私たち既に(わずかに異なる構文とは別に)既にありますか? – Jon

+0

基本クラスからいくつかのクラスを拡張したいが、特性を使用しているときは、構文が短くなる。 – Meglio

+1

@Meglio:ちょうどそれを行う: 'クラスCはベース{use T}を拡張する'。 – hakre

答えて

5

クラスのみを拡張できます。形質はではなく、クラスです。それらはクラスによって使用/包含されることができますが、クラス自体ではありません。形質を伸ばす必要があると思うなら、おそらくクラスでなければならず、おそらく抽象的なものであり、形質ではないはずです。従って

+0

ここでの考え方は、実際に形質を広げる方法ではなく、構文が短いことです。 – Meglio

+3

@Meglio:構文には長さがないため、短い構文はありません。 – hakre

+0

短い表記法。 – Meglio

31

PHPマニュアル状態:

形質PHPなどの単一継承言語でコードを再利用するための機構です。特性は、異なるクラス階層にあるいくつかの独立したクラスで自由にメソッドのセットを再利用できるようにすることによって、単一継承のいくつかの制限を減らすことを意図しています。 Traitとクラスの組み合わせのセマンティクスは、複雑さを軽減し、多重継承やMixinsに関連する典型的な問題を回避する方法で定義されています。

特性を拡張しようとしている場合は、おそらくクラスでなければなりません。 1つのクラスで他のクラスで使用したいメソッドのセットを持っていても、クラスを拡張するのが不適切だと感じたら(例えばclass Animal extends Vehicle)、PHP 5.4ではそれが特性としてうまくいく可能性があります。

より直接的に質問に答えるために、あなたは形質を「伸ばす」ことはできませんが、自分自身が他の形質を使う形質を作り出すことができます。 PHPマニュアルの通り:

trait Hello { 
    public function sayHello() { 
     echo 'Hello '; 
    } 
} 

trait World { 
    public function sayWorld() { 
     echo 'World!'; 
    } 
} 

trait HelloWorld { 
    use Hello, World; 
} 

class MyHelloWorld { 
    use HelloWorld; 
} 

これは、あなたの特性を論理グループに維持し、いくつかのモジュール性を導入する方法と考えることができます。

編集:基本クラスの形質を使うことは、それを拡張するどのクラスにも属していることを意味し、その特性は基底クラスの関数よりも優先されることに注意することは価値があると思います。 。子クラスに入れると、親/基底クラスではその特性を利用できなくなります。

Parent > Trait > Child 

http://php.net/manual/en/language.oop5.traits.php

11

あなたは多少特色を拡張することができます。 mrleeの答えを広げて、useの形質を使うと、そのメソッドの名前を変更できます。

セイたとえば、あなたのフレームワークによって定義された「親」形質を持っている:

trait FrameworkTrait { 
    public function keepMe() { 
     // Framework's logic that you want to keep 
    } 

    public function replaceMe() { 
     // Framework's logic that you need to overwrite 
    } 
} 

は単に、親トレイトに引っ張る何か他のものにそのreplaceMeメソッドの名前を変更し、独自のreplaceMe方法を定義します。

trait MyTrait { 
    use FrameworkTrait { 
     FrameworkTrait::replaceMe as frameworkReplaceMe; 
    } 

    public function replaceMe() { 
     // You can even call the "parent" method if you'd like: 
     $this->frameworkReplaceMe(); 

     // Your logic here 
    } 
} 

そして、あなたのクラスで:

class MyClass { 
    use MyTrait; 
} 

は今これを行うことができ、このクラスのオブジェクト:

$obj = new MyClass(); 

$obj->keepMe();    // calls "parent" trait 
$obj->replaceMe();   // calls "child" trait 
$obj->frameworkReplaceMe(); // calls "parent" trait 
関連する問題