2

私はYiiアプリケーションを開発してきました。そして、モデルの振る舞いで、ある種の「抽象的な」メソッドを宣言することが可能かどうか疑問に思っています。宣言の直後に使用することは不可能であることを私は知っています:

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

このクラスのインスタンスが必要だからです。しかし、Yiiが完全な魔法であることも知っています:)

必須の順序で動作からメソッドを再宣言する所有者クラスを作成したいだけです。もちろん、動作に加えてインターフェースを使用することもできますが...

伝えたいことがなかったり、はっきりしないことがあったらごめんなさい。ただ聞いてください、そして私は私が何を意味するかを説明しようとします。

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

前もって感謝します。

UPD

Yiiは単なるPHPであることを私は理解しています。PHPを拡張しません。それはその上の上部構造です。また、PHPには多重継承がないため、多重継承はありません。

動作メソッドはabstractキーワードを使用して宣言できないことを理解しています。そのため、私は「abstract」という単語を引用符で囲んで書いています。しかし、何でも。私は行動がどのように機能するかを知っています。

私の質問は、モデル(CActiveRecordの子など)に何らかのメソッドを宣言するように強制できるかどうかでした。

たとえば、私の目的のために、私は次のようなことをすることができます:

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

したがって、この動作をモデルにアタッチしてメソッドdoFantasticThingsを呼び出すと、このメソッドはmodel(owner)からメソッドprepareForFantasticを呼び出そうとします。また、モデルにメソッドprepareForFantasticがない場合、宣言されていないメソッドが呼び出されるため、宣言された新しい例外がスローされます。

私は自分の質問に自分で答えたようです:)これについてどう思いますか?

UPD2

はい、「abstract」メソッドを呼び出さないと、宣言されていないことがわかりません。これは、解釈可能な言語の「魅力」です:)コードが実行されるまで、エラーがあるかどうかはわかりません。ただし、これについてできるだけ早く知ることができれば素晴らしいと思います。たとえば、FantasticBehavior-classのインスタンスがモデルにアタッチされると、の子をスローしてCException、モデルで宣言する必要のあるメソッドを示すことができます。これを達成するために、以下のようなものを使用できます。

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');
    }

}

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

attachBehaviorイベントがあるかどうかわかりません。もしそうなら、attachメソッドをオーバーライドする代わりにそれを使用することができます。

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

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

たぶん将来、私はYiiを拡張して、有名で金持ちになるのでしょうか?:))

4

1 に答える 1

2

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

いいえ、 YiiのBehaviorsを使用して抽象メソッドをCActiveRecordモデルに「アタッチ」することはできません。Behaviorが行うことはすべて、の巧妙なオーバーライドであり__call()__get()多重継承の錯覚__set()を与えます。(これはそれについての良い記事です)。ビヘイビアーは、抽象クラスやインターフェースなどのコア言語機能に対する真の「多重継承」サポートを提供しません。したがって、そのビヘイビアーをアタッチしてクラスに追加しても、エラーが発生します。doSomethingFantastic()CActiveRecord

もちろん、他のビヘイビアーが拡張する抽象的なビヘイビアーを宣言することもできます。したがって、拡張して実装されSuperFantasticBehavior別のビヘイビアを作成した場合は、問題ありません。ただし、メソッド自体を宣言する必要はありません。FantasticBehaviordoSomethingFantastic()doSomethingFantastic()CActiveRecord

もう少し深く理解するために:YiiのCComponent :: _ call()オーバーライドの構造は、メソッドを呼び出すときに、最初に動作のいずれかにそのメソッドがあるかどうかを確認し、クラス自体でメソッドを呼び出します。

動作は最初はクールに見えますが(ミックスイン!)、PHPは単一クラスの継承言語であり、保持は単純であることを覚えておくとよい場合があります。;)

アップデート:

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

代わりに、実行時に「宣言されていないメソッド」エラーが表示されます(おっしゃるように)。ただし、そのメソッドが実際に呼び出されるまで表示されません。つまり、抽象的な定義で得られるような早期の警告は表示されません。そして、そのメソッドが呼び出されない場合、エラーは発生しません。つまり、抽象defが行うのと同じように、宣言を実際に「義務付ける」わけではありません。

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

乾杯

于 2012-03-01T21:12:09.383 に答える