3

子クラスから保護されたクラス メソッドにアクセスするには、少なくとも 2 つの基本的な方法を使用できます。

parent::myMethod();

$this->myMethod();

子クラスでオーバーライドする必要がない場合は、次のようにする必要があります。

function myMethod() {
   ...
   parent::myMethod();
   ...
}

それを呼び出す最も推奨される方法はどれですか? 個人的には、 $this->myMethodよりもparent::myMethod()を使用する方が快適だと感じています。最初のメソッドでは、このメソッドが継承されていることがすぐにわかるからです。しかし、パフォーマンスとベスト プラクティスの点でどちらがよいかはわかりません。

編集:

これを確認してください。これは私の質問の実際のケースです。これは CodeIgniter を使用していますが、慣れていない場合でも、次のように取得できる可能性があります。

class Admin_Controller extends CI_Controller {

    protected function validate_form($validation) {
            $this->load->library('form_validation');
            // This will validate the form sent against the validation rules group specified in $validation
            if ($this->form_validation->run($validation) == false) {   
                    throw new Exception('There are errors in the form');
            }
    }

}

class Articles extends Admin_Controller {

    function save($id) {
            $this->validate_form(strtolower(get_class($this));
            // OR
            parent::validate_form(strtolower(get_class($this));
            // Other actions
            ....
    }

}

class Login extends Admin_Controller {

    function signIn() {
            $this->validate_form(strtolower(get_class($this));
            // OR
            parent::validate_form(strtolower(get_class($this));
            // Other actions
            ....
    }

}
4

4 に答える 4

5

彼らは2つの異なることをします。キーワードのセマンティックは、parentその親クラスへの転送呼び出しを行うようなものです。ただし、のセマンティクスは$this->method()、メソッドが呼び出されたインスタンスがそのメソッドを宣言していない場合にのみ、その呼び出しを親クラスに転送するようになっています。また、子には祖父母だけでなく親もいる可能性があるため、プロトタイプの設計においても慎重に考慮する必要があることに注意することも重要です。

メソッドをオーバーライドしたくない場合は、メソッド プロトタイプ宣言でfinalキーワードを使用する必要があります。

class MyClass {
    final protected function myMethod() {
    }
}

これにより、拡張クラスがメソッドをオーバーライドできないことが保証されます。拡張クラスが次のコードのようにこのメソッドをオーバーライドしようとすると、致命的なエラーが発生しますFatal error: Cannot override final method MyClass::myMethod()

class MyOtherClass extends MyClass {
    public function myMethod() {
    }
}

また、これにより、コードを読む人にメソッドが最終的なものであり、オーバーライドできないことを明確に示すため、コードが読みやすくなり、エラーが発生しにくくなります。

また、アプローチの根本的な問題 ( parent::myMethod()vs.を使用する場合) は、クラスが親の$this->myMethod()である場合に何が起こるかを考慮していないことです。たとえば...

class Father {
    protected function myMethod() {
        return __METHOD__;
    }
}

class Child extends Father {
    public function myMethod() {
        return __METHOD__;
    }
}

class GrandChild extends Child {
    public function myOtherMethod() {
        echo parent::myMethod(), "\n"; // Child::myMethod
        echo $this->myMethod(), "\n";  // Child::myMethod
    }
}

$obj = new GrandChild;
$obj->myOtherMethod();

ご覧のとおり、どちらも、父親のメソッドを取得するつもりだったとしても、子メソッドを提供します。拡張クラスでメソッドをオーバーライドするつもりがなく、オブジェクト コンテキストから $this->myMethod() を呼び出すときは常に問題ない場合は、メソッドを final として宣言するだけです。

于 2012-12-07T14:05:56.267 に答える
1

私が理解している限り、それらは2つの異なるものです。

$thisは、クラスのインスタンスを参照するために使用され、オブジェクトが作成されると使用可能になります。したがって、親ではなく、子クラスのオブジェクトを参照します。

は、サブクラスで親のメソッドを拡張する正しい方法です。これは親クラスを参照し、クラス名の変更を多くのレベルで行う必要がないという追加の利点があります。自分も似ています。

例として、以下の 2 つの実装を参照してください。

  1. 親キーワードでアクセスする
  2. これでアクセスすると、予期しない動作が発生します。

お役に立てれば幸いです。

于 2012-12-07T14:09:24.480 に答える
0

parent::method() を呼び出すと、$this->method() とは異なるメソッドになります。子クラスでオーバーライドすると、異なる値が返される場合があります

于 2012-12-07T13:30:14.083 に答える