1

抽象クラス内で一般的なメソッドを呼び出す適切な方法について少し混乱しています。次のコードを使用します。

abstract class Transaction {

    abstract public function process();
    abstract public function set_status();

    protected function get_valid_statuses() {
        return array(
            'pending',
            'approved'
        );
    }

}

class Purchase extends Transaction {

     public function process() {
     }

     public function set_status( $status ) {

          //check against valid statuses
          $valid = Transaction::get_valid_statuses();

          .......

     }

}

明らかに、このコードは完全にはほど遠いですが、この例では十分です。私はそれをテストしたので、なぜこれが機能するのか疑問に思っています。Purchase クラス内で set_status メソッドをget_valid_statuses()使用する場合、通常は静的メソッドに使用するスコープ解決演算子を使用してメソッドを呼び出しています。以下を使用してメソッドを呼び出すと想定していました。

$valid = Transaction->get_valid_statuses();

しかし、クラスが実際にインスタンス化されたことがないため、これは機能しないと思います。誰かが明確化してください。抽象クラスまたはスコープ解決演算子に関する PHP ドキュメントから理解を見つけることができませんでした。

ありがとう!

4

4 に答える 4

1

エラー報告をオンにすると、厳密なエラーが表示されます:

非静的メソッド トランザクション ::get_valid_statuses() を静的に呼び出すべきではありません

このエラーはすべての 5.x php バージョンに存在するため、下位互換性のために機能します。php4 の暗い時代には、クラス内で静的メソッドを宣言する方法がなかったので、すべてのメソッドは次のように単純に宣言されていました。function foo(){ }

ここで静的メソッドについて学ぶことができます。簡単に言うと、このメソッドを呼び出す前にクラスをインスタンス化する必要はありませんが (abstractキーワードのためにインスタンス化できません)、クラス名とスコープ解決演算子を使用して呼び出します。

$thisこのメソッド内に現在のオブジェクト ( ) への参照がないため、これも機能します。を使用して、このメソッド本体をそのプロパティ/メソッドのいずれかを参照するように変更する$thisと、致命的なエラーで終了します。

于 2013-09-13T21:11:20.927 に答える
0

その::演算子 (スコープ解決演算子) を使用しても、常に STATIC メソッド呼び出しがトリガーされるとは限りません。

あなたの場合、そうです。クラス名を使用しています。ただし、静的呼び出しをトリガーしない特別なキーワードがあります: self, parent, static.

それに加えて、現在の独自のオブジェクトを参照する変数もあります: $this.

したがって、独自のメソッドを持っているクラスを継承するときはいつでも、それらを現在のクラスにあるように扱い、 を呼び出すことができます$this->get_valid_statuses()。これにより、現在のクラス、または任意の親クラスまたは親の親クラスにその関数が存在するかどうかが降順で動的にチェックされ、最初に見つかった関数が呼び出されます。

親クラスの関数を確実に呼び出したい場合は、 を使用しますparent::get_valid_statuses()。CURRENT クラスのメソッドを確実に呼び出したい場合は、self::get_valid_statuses().

キーワードは、クラスで静的メソッドを継承する際に重要な役割を果たしますが、静的メソッドは通常、役立つというよりも悪であるため、マニュアルのみstaticを参照したいと思います。

クラスを継承するときはどうすればよいですか?場合によります。$this動作します。また、現在のクラスでそれをオーバーライドしてget_valid_statuses()拡張することもできます。

parent::get_valid_statuses()Purchaseクラスがオーバーライドget_valid_statuses()し、親クラスからステータスを取得したい場合にのみ、実際に呼び出す必要があります。この場合$this->get_valid_statuses()、 を呼び出すことはできません。これは、同じクラスのメソッドを再度呼び出すことになり、終わりのないループにつながるからです。そのため、最もよく使用parent::$this->れる接頭辞です。

于 2013-09-13T21:25:44.070 に答える