9

ですかabstract function xxx

プライベートメソッドも仮想であることを示しているように見えるテストを作成しましたか?

class a {
 private function test()
 {
  echo 1;
 }
}

class b extends a {
 private function test()
 {
  echo 2;
 }
 public function call()
 {
  $this->test();
 }
}

$instance = new b;
$instance->call();

出力は2

4

3 に答える 3

18

PHP では、すべての非公開関数は仮想ではないため、明示的に仮想として宣言する必要はありません。

メンバー関数を単に宣言abstractすることは、基本クラスが実装を提供できないことを意味しますが、すべての派生クラスは実装を提供する必要があります。メソッドを抽象として定義することは、C++ で次のことを行うことと同じです。

virtual void foo() = 0;

これは単に、派生クラスが実装する必要があることを意味しますfoo();

編集:編集された質問について

b::call()アクセスできませんa::test()。このため、プライベート関数を呼び出すと、それが呼び出されたクラス内の関数のみが呼び出されます。

編集:コメントについて:

(ウィキペダより)

オブジェクト指向プログラミングでは、仮想関数または仮想メソッドは、同じシグネチャを持つ関数によって継承クラス内で動作をオーバーライドできる関数またはメソッドです。

C++ では対価を明示的に示すという考え方により、派生クラスが関数をオーバーライドできるように、関数を仮想として宣言する必要があります。

class Foo{
public:
    void baz(){
        std::cout << "Foo";
    }
};
class Bar : public Foo{
public:
    void baz(){
        std::cout << "Bar";
    }
};

int main(){
    Foo* f = new Bar();
    f->baz(); //baz is not virtual in Foo, so the output is Foo
}

baz を仮想に変更する

class Foo{
public:
    virtual void baz(){
        std::cout << "Foo";
    }
};
//Same Bar declaration

int main(){
    Foo* f = new Bar();
    f->baz(); //baz is virtual in Foo, so the output is Bar as it will call the derived function
}

f上記のサンプルの変数がタイプであった場合、Bar*または目的のタイプが既知であるため、仮想であるかBarどうかは問題ではないことに注意してください(プログラマーが明示的に指定しました)Foo::baz()

于 2010-03-21T16:06:51.010 に答える
4

call()この例では、b が実装の詳細を知る必要はなく、実行方法を指定できる典型的な特殊化パターンを示していませんでしtest()た。そして、それは1残念ながら戻ってきます。ただし、関数を private ではなく protected と宣言することで、期待どおりに機能します。

class a {
    protected function test()
    {
        echo 1;
    }
    public function call() {
        $this->test();
    }
}

class b extends a {
    protected function test()
    {
      echo 2;
    }
}

$instance = new b();
$instance->call();
于 2012-11-28T17:59:18.000 に答える
2

$this->meth() ではなく static::meth() ではなく static キーワード (php 5.4) を使用します

于 2013-03-10T20:52:16.133 に答える