2017-05-08 6 views
0
public class ClassA { 

    int value = 50; 

    public void display(){ 

     System.out.println("ClassA displaying value:"+ value); 
    } 

} 

public class ClassB extends ClassA { 

    int value = 25; 

    public void display(){ 

     System.out.println("ClassB displaying value:"+ value); 
    } 

} 


public class Test { 

     public static void main(String[] args) { 

      ClassA objA = new ClassB(); 
      ClassB objB = new ClassB(); 

      System.out.println(objA.value); --> 50 
      System.out.println(objB.value); --> 25 

      objA.display(); --> ClassA Displaying value: 25 
      objB.display(); --> ClassB Displaying value: 25 
    } 

} 

誰かがオブジェクト参照はA級であり、それはメソッド表示を探しOBJAは、コンパイル時に、オーバーライドでスーパー値50スーパークラスリファレンス

印刷される理由を説明することができます()クラスAで。そのメソッドがClassAで使用可能な場合、実行時に実際に作成されるオブジェクトはClassBであり、ClassBのdisplay()メソッドはClassAのdisplay()メソッドをオーバーライドします。

しかし、クラスプロパティ "値"を印刷するとどうなりますか?

ClassA objA = new ClassB(); 
System.out.println(objA.value); 

ここで、参照はClassAであり、実際のオブジェクトはClassBである。だから私はclassBの値25を期待しています。しかし、classAの値50が印刷されています。

私の理解が間違っている場合は修正してください。..アドバンス

おかげ

答えて

0

まず、私は少し文言の間違いを訂正してみましょう:オーバーライドで

コンパイル時オブジェクト参照はClassAであり、ClassAのDisplay()メソッドを探します。

いいえ、メソッドはコンパイル時に呼び出されません。実行時に呼び出されます。それはClassB方法を探しますので、実行時には、オブジェクトは、今あなたがをオーバーライドの違いを理解する必要があり、なぜ2つのdisplay通話ボットプリント25

オーケーである、実際にClassBの目的でありますおよびhiding。メソッドdisplayがオーバーライドされるので、objAがタイプClassAであっても、には実際にClassBのインスタンスが含まれているため、ClassBのメソッドが呼び出されます。

valueは、一方、非表示になっています。 valueにアクセスするとobjAはタイプClassAの変数であるためobjAにはClassBというオブジェクトが含まれていても、にはvalueという値があります。

あなたがvalueを上書きする場合は、そのメソッド行う必要があります。

class ClassA { 

    public int getValue() { return 50; } 

    public void display(){ 

     System.out.println("ClassA displaying value:"+ getValue()); 
    } 

} 

class ClassB extends ClassA { 

    public int getValue() { return 25; } 

    public void display(){ 

     System.out.println("ClassB displaying value:"+ getValue()); 
    } 

}