2012-02-29 11 views
2

私はYiiアプリケーションを開発しています。モデルの振る舞いで何らかの抽象メソッドを宣言することが可能かどうかは疑問です。私たちは、このクラスのinstanseを必要とするのでYiiビヘイビアの "抽象"メソッド

abstract class FantasticBehavior extends CActiveRecordBehavior 
{ 
    public abstract function doSomethingFantastic(); 
} 

:私はそれは不可能直接次の宣言を使用することを知っています。でも、私はYiiが完全な魔法であることを知っています:)

私は、義務的な順序で振る舞いからメソッドを再宣言するためにオーナークラスを作りたいと思います。確かに、私は行動に加えてインターフェイスを使用することができますが...

私は何かを逃したか、何かが明確でない場合は申し訳ありません。尋ねると、私は何を意味するのか説明しようとします。

誰かがこれについて何か知っていますか?

ありがとうございます。

UPD

私はYiiのがちょうどPHPであることを理解してください。 PHPを拡張するものではありません。それは上の上層部です。 PHPにはないので、多重継承はありません。

抽象的なキーワードを使用して動作方法を宣言することはできません。それで、私は引用符で「抽象的な」という言葉を書いたのです。しかし、何でも。私は行動がどのように働くか知っています。

どういうわけか、モデル(たとえば、CActiveRecordの子)に何らかの方法を宣言することができたかどうかという質問でした。

は、例えば、私の目的のために、私はこのような何かを行うことができます。

class FantasticBehavior extends CActiveRecordBehavior 
{ 
    public function doFantasticThings() 
    { 
     $this->owner->prepareForFantastic(); 
     // some code 
    } 
} 

をので、私は私のモデルと呼び出し方法doFantasticThingsにこの動作を添付した場合、このメソッドは、モデルからメソッドprepareForFantasticを呼び出すようにしようとします(所有者)。モデルにメソッドprepareForFantasticがない場合、宣言されていないメソッドが呼び出されるため、新しい例外がスローされます。

自分の質問に自分自身が答えたように見えます。これについてどう思いますか?

UPD2

はい、私たちは「抽象」メソッドを呼び出していない場合、我々は、それが宣言されていないことを知らないだろうことを知っています。解釈可能な言語の "魅力"です。コードが実行されるまでエラーがないかどうかはわかりません。しかし、できるだけ早くこのことを知ることができればすばらしいでしょう。たとえば、FantasticBehavior -classのインスタンスがモデルに添付されると、CExceptionの子を投げて、モデルで宣言する必要のあるメソッドを示すことができます。これをachiveするために、我々は、下記のようなものを使用することができます

class FantasticBehavior extends CActiveRecordBehavior 
{ 

    public function attach($owner) 
    { 

     if(!/*$owner has declared methods list this->abstractMethods*/) 
     { 
      throw new CAbstractMethodNotDecalared('....'); 
     } 

     parent::attach($owner);  
    } 

    public function abstractMethods() 
    { 
     return array('prepareForFantastic'); 
    } 

} 

私たちは、クラスCBehaviorからメソッドattachをオーバーライドして、「抽象」メソッドが宣言かどうかを確認する必要があります。メソッドabstractMethodsは、リスト "抽象"メソッドを取得するために使用されます。

attachBehaviorイベントが存在するかどうかわかりません。その場合は、attachメソッドをオーバーライドする代わりに使用することができます。

このアイデアの使用「抽象」メソッドを使用する動作の基本クラス。

あなたはこれについてどう思いますか?

多分将来私はYiiの延長を行い、有名かつ豊かになるでしょうか? :))

答えて

2

これは説明するのは少し混乱するかもしれません...

いいえ、あなたはYii's Behaviorsを使用してCActiveRecordモデルに抽象メソッドを「添付」することはできません。すべての行動は、__call()__get()および__set()の巧妙なオーバーライドで、錯覚の多重継承です。 (This is a good article about it)。動作にtrueを指定しない抽象クラスやインタフェースなどのコア言語機能を「多重継承」でサポートしています。したがって、その行動を添付してCActiveRecordクラスにdoSomethingFantastic()を追加すると、エラーが発生します。

あなたはです。はもちろん、他のビヘイビアが拡張する抽象的なビヘイビアを宣言します。したがって、FantasticBehaviorを拡張してdoSomethingFantastic()を実装した別のSuperFantasticBehaviorビヘイビアを作成した場合は、にはとなります。 CActiveRecord自体でdoSomethingFantastic()メソッドを宣言する必要はありません。少し深く理解するため

:Yiiの者CComponent::_call()オーバーライドが構成されている方法で、あなたはそれが最初の行動のいずれかがそのメソッドを持っているかどうかを確認し、クラス自体のメソッドを呼び出すメソッドを呼び出します。

最初は行動が冷静だったようですが(mixins!)、時にはPHPがsingle class inheritance languageであり、保持が簡単であることを覚えておくとよいでしょう。 ;)

UPDATE:

違いは、この場合には抽象メソッドを使用することができれば、あなたのコード(任意のコードを実行しようとすると、「クラスのメソッドを実装しなければなりません」というエラーを参照してくださいねということです)あなたのIDEはエラーを強調表示します。これは、コンパイル時のエラー(実際にはPHPのような解釈された言語には存在しない)のほうが多いです。

代わりに、実行時に「宣言されていないメソッド」というエラーが表示されます。しかし、そのメソッドが実際に呼び出されるまで、あなたはそれを見ることはできません。つまり、抽象定義があなたに与えるような素晴らしい初期警告を得られないことを意味します。そのメソッドがでない場合は、と呼ばれることはありません。このエラーは発生しません。つまり、抽象的なdefと同じ方法で宣言を実際に「義務づけ」ているわけではありません。

申し訳ありません初期の回答があまり基本的ではないレベルで開始していた場合は、誤解がないことを確認したかっただけです。興味深い議論であり、抽象宣言が本当に何をしているかについてもっと考えさせてくれました。ありがとう、幸せなコーディング! :)

乾杯

+0

こんにちは。お返事をありがとうございます。最新の記事を参照してください。 –

+0

こんにちはもう一度:)更新された投稿を参照してください:)そしてあなたにもうれしいコーディング。 –

関連する問題