20

このコードの出力が得られる理由を理解するのが困難です。

<?php

class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }

    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }

    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new foo();
$myFoo->test(); 
?>

したがって、Foo は Bar を拡張します。$myfoo はクラス Foo のオブジェクトです。Foo には test() というメソッドがないため、親の Bar から拡張します。しかし、なぜ test() の結果は

Bar::testPrivate 
Foo::testPublic

この親のメソッドが子でオーバーライドされているときに、最初のメソッドが Foo::testPrivate ではない理由を教えてください。

事前にどうもありがとうございました!

4

6 に答える 6

12

おそらくtestPrivate、名前がすでに示しているように、プライベートメソッドであり、クラス継承によって継承/上書きされないためです。

php.netのマニュアルページでは、おそらくそこからコードを取得したと明示的に述べていますWe can redeclare the public and protected method, but not private

したがって、正確には次のようになります。子オブジェクトのみの場合、子クラスはメソッドを再宣言しませんtestPrivateが、代わりに「スコープ」内に独自のバージョンを作成します。test()親クラスで定義されているように、parent にアクセスしますtestPrivate

test子クラスで関数を再宣言する場合は、childs? testPrivate()メソッドにアクセスする必要があります。

于 2012-10-24T07:07:42.180 に答える
6

プライベート メソッドは、宣言しているクラス以外には見えません。親クラスから呼び出すためtestPrivate、アクセスできる唯一のメソッドは、メソッドの独自の宣言です。したがって、表示される出力が得られます。ただし、アクセス修飾子がprotectedである場合、保護されたメソッドは継承チェーン全体で表示されるため、期待どおりの出力が得られます。

于 2012-10-24T07:07:41.010 に答える
5

privateメンバーはオーバーライドできません。パブリックおよび保護されたメンバーのみがオーバーライドできます。これは、実際にtestPrivateはオーバーライドされていないため、それBar見ることができず、独自の を呼び出していることを意味しtestPrivateます。

于 2012-10-24T07:07:00.730 に答える
5

なぜならprivate手段private。他のクラスは、子クラスでBar::testPrivate()さえ知らないため、知らないものをオーバーライドすることはできません。

Foo::testPrivate()内でのみ使用できますFoo。それprivateがすべてだからです。

詳細:プライベート メソッドをオーバーライドするときの奇妙な動作

于 2012-10-24T07:07:43.247 に答える
3

これは PHP 固有のものではありません。継承規則では、保護されたパブリック関数をオーバーライド可能にする必要があります。プライベート関数には独自のスコープがあり、一般化されたクラスには表示されません。

Java での同じ状況、同じ結果を以下に示します。

Bar::testPrivate

Foo::testPublic

警告が表示される場合を除いて

The method testPrivate() from the type Foo is never used locally    Foo.java    

Javaがコンパイルされているためです。

public class Bar 
{
    public void test() {
        this.testPrivate();
        this.testPublic();
    }

    public void testPublic() {
        System.out.println("Bar::testPublic\n)");
    }

    private void testPrivate() {
        System.out.println( "Bar::testPrivate\n");
    }
}

public class Foo extends Bar {
    public void testPublic() {
        System.out.println("Foo::testPublic\n");
    }

    private void testPrivate() {
        System.out.println("Foo::testPrivate\n");
    }

    public static void main(String[] args) {
        Foo myFoo = new Foo();
        myFoo.test();
    }
}
于 2012-10-24T07:15:01.657 に答える
3

マニュアルから:

private として宣言されたメンバーには、そのメンバーを定義するクラスのみがアクセスできます。

テスト関数は基本クラス Bar で実行されるため、独自のクラスのプライベート関数にアクセスします。

于 2012-10-24T07:06:41.460 に答える