1

SCJP 6試験の勉強中に、私はテスト試験でこの質問に遭遇しました。

class A{  
    private static String staticProperty = " a ";  
    String getStaticProperty() { return staticProperty; }  
}  

class B extends A {  
    private static String staticProperty = " b ";  
    public static void main(String[] args){  
        new B().go(new A());  

    }  
    void go(A t){  
        String s = t.getStaticProperty() + B.staticProperty + staticProperty + (new B().getStaticProperty());  
        System.out.println(s);  
    }  
}  

出力は何ですか?

ここでの出力はa b b a

私は完全に理解a b bしていますが、最後の「a」は理解していません。メソッドを継承し(この場合、BはAからgetStaticProperty()を継承します)、そのメソッドが親(staticProperty)から静的変数を返し、これを子で再定義する場合は、常に親の静的変数を使用します価値??

ちなみに、静的識別子を削除してstaticFieldをクラスのインスタンスメンバーにすると、同じ結果が返されます。アクセス修飾子をプライベートからパブリックまたはその他に変更すると、同じ結果が返されます。見たいものを取得するには、getStaticPropertyメソッドをオーバーライドする必要がありました。

4

5 に答える 5

4

フィールドアクセスは、メソッドアクセスのように動的ディスパッチの対象ではありません。つまり、フィールドをオーバーライドすることはできません。クラスAのこの行:

String getStaticProperty() { return staticProperty; }  

したがってstaticProperty、クラスAのフィールドを参照します。同じ名前のクラスBのフィールドは無関係です。つまり、スーパークラスフィールドを非表示にし、クラスBのすべてのコードがこのフィールドを使用します。SunのJavaチュートリアルには、この問題について次のように書かれています。

クラス内で、スーパークラスのフィールドと同じ名前のフィールドは、タイプが異なっていても、スーパークラスのフィールドを非表示にします。サブクラス内では、スーパークラスのフィールドをその単純な名前で参照することはできません。代わりに、フィールドにアクセスする必要がありますsuper。これについては、次のセクションで説明します。一般的に、フィールドを非表示にするとコードが読みにくくなるため、非表示にすることはお勧めしません。

于 2009-12-15T15:53:22.740 に答える
3

new B().getStaticProperty()は、スコープが に設定されているため、 の静的プロパティAを返すメソッドを呼び出しています。AA

于 2009-12-15T15:37:11.380 に答える
1

Java では関数は仮想ですが、クラス メンバー (静的またはインスタンス) は仮想ではありません。したがって、B の の定義はstaticPropertyA の定義を覆い隠しているかもしれませんが、それをオーバーライドすることはありません。

// in B
String fromChild = staticProperty; // == "b"
String fromParent = A.staticProperty; // == "a", was masked but not overridden

B で定義された変数に A をアクセスさせる唯一の方法は、A でゲッター関数を定義し、それを B でオーバーライドすることです。

于 2009-12-15T15:51:17.113 に答える
1

new B()このような継承の問題について考えるとき、が呼び出されたときに何が起こるかを考えると役立つことがあります。B のコンストラクターが実行されると、最初に実行される操作は (A のコンストラクターへの明示的な呼び出しがないため) ですsuper()。この時点で、A のインスタンスが作成され、このオブジェクト内で、getStaticProperty()メソッドは明らかに A の を参照しstaticPropertyます。次に、B のコンストラクターの本体が実行されます (これも、A のコンストラクターの実行が成功した後でのみ)。A のコンストラクgetStaticProperty()ターによってインスタンス化されたメソッドを変更またはオーバーライドすることは何もしないため、そのメソッドの動作も変更されません。

これは最初は混乱するように思えるかもしれませんが、さまざまな継承の問題の意味を考えるのに役立つ方法です。

于 2009-12-15T18:03:36.707 に答える
0

getStaticProperty() はクラス A で定義されたメソッドです。メソッドはクラス B でオーバーライドされないため、クラス A のメソッドが使用されます。A は B の静的プロパティを「見る」ことができないため、独自の値を返します。

于 2009-12-15T15:46:45.667 に答える