2012-10-24 19 views
19

は、私たちは、このコードの出力を取得する理由を理解するのに困難を抱えています。 $ myfooはFooクラスのオブジェクトです。 Fooはtest()と呼ばれるメソッドを持たないため、親のBarからそれを拡張します。しかし、なぜテストの結果は、()最初はFOO :: testPrivate、ときに、この親のメソッドは、子でオーバーライドされていない理由継承と視界PHP

Bar::testPrivate 
Foo::testPublic 

はあなたが私を説明していただけますでしょうか?

ありがとうございます! manualから

答えて

13

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

あなたはおそらくそれからそのコードが明示的にそう We can redeclare the public and protected method, but not private

は、まさに起こるが追従していることを述べましたphp.netのマニュアルページ

:子クラスはメソッドtestPrivateを再宣言ではなく、それ自身のバージョンを作成しません。子オブジェクトの場合のみ "スコープ"内にあります。 test()は親クラスで定義されているため、親のtestPrivateにアクセスします。

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

3

:民間のみ がメンバーを定義するクラスによってアクセスすることができるよう

メンバーが宣言しました。

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

5

privateメンバーを上書きすることはできません。公開メンバーと保護されたメンバーだけが上書きできます。実際にはtestPrivateではなく、であることを意味します。したがって、Barはそれを見ることはできず、依然として独自のtestPrivateを呼び出します。

5

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

5

privateprivateを意味するためです。子供クラスでさえ、他のクラスはBar::testPrivate()を知らないので、知らないことを無視することはできません。

Foo::testPrivate()Fooの中でのみ使用できます。これは、privateのすべてです。

詳細情報:Strange behavior when overriding private methods

3

これはPHP固有のものではありません。継承ルールでは、protectedおよびpublic関数をオーバーライド可能にする必要があります。プライベート関数は独自のスコープを持ち、一般化されたクラスでは見えません。 Javaがコンパイルされているので、あなたが警告

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

を取得する可能性があります除き

Bar::testPrivate 

Foo::testPublic 

、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(); 
    } 
}