2013-08-23 97 views
0

繼承人的代碼:有人可以解釋我這種多態性的輸出嗎?

class A{ 
    int data=10; 
    void show1(){ 
     System.out.println("In A="+data); 
    } 
} 

class B extends A{ 
    int data=20; 
    void show2(){ 
     System.out.println("In B="+data); 
    } 



} 


public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     System.out.println("Data1="+b.data); 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

而且繼承人的輸出:

Data1=20 
Data2=20 
In A=10 
In B=20 

在數據1 = 20的輸出應該是10,不是20 ...但我覺得我失去了一些東西。請幫我這個

好了,感謝您的幫助,但一個新的疑問:如果 我改變的主要方法會發生什麼:

public static void main(String args[]){ 
      A a=new B(); 
      System.out.println("Data1="+a.data); 
      System.out.println("Data2="+a.data); 
      a.show1(); 
      a.show2(); 
     } 

你去那裏。

+0

你爲什麼認爲它應該是'10'? –

+0

爲什麼'Data1'必須是10? –

+0

它是20,因爲您重新聲明瞭該字段,因此它使用的是聲明字段的值,而不是超類中字段的值。實際上你應該嘗試避免重複的字段名稱(超類和子類中存在的字段名稱),因爲它可能會避免很多混淆。 –

回答

1

類字段不會被繼承。請注意,您在AB這兩個類中都有相同的int data字段。這叫做Hiding

0

由於您已經重寫了類B中的數據變量,因此它將打印最新值。由於您將B類中的「數據」重估爲20,這就是它將顯示的內容。

1

爲了「感覺」多態的,我們需要改變你的代碼位的功率:

class A { 

    int data=10; 
    void show(){ 
     System.out.println("In A="+data); 
    } 
} 

class B extends A { 

    int data=20; 

    @Override 
    void show(){ 
     System.out.println("In B="+data); 
    } 

    public static void main(String args[]){ 
     A a = new A(); 
     A b = new B(); 
     a.show(); 
     b.show(); 
    } 
} 

現在,你可以看到,無論ab被聲明爲A類型的 - 但分配是造成差異的原因。此外,我們可以創建類型A的陣列,並用這兩種類型的對象容納它(A以及B):

A[] arr = new A[3]; 

//讓我們添加一些東西;

arr[0] = new A(); 
arr[1] = new B(); 
arr[2] = new A(); 

現在很容易看到的最後一個循環將polimorphism多麼美麗worksL

for (int i=0; i<arr.length; i++){ 
    arr[i].show(); 
} 

打印:

In A 10 
In B 20 
In A 10 

所有我們知道的是,數組中存放它們的子對象A的類型 - 我們可以依靠每個對象來調用「正確」的方法show()。這是多態!

1
Within a class, a field that has the same name as a field in the superclass hides 
the superclass's field, even if their types are different. 

這可以在Hiding fields

因此可以發現,它打印20.

0

B類的對象具有兩個字段,這兩個命名data,但作爲Luiggi暗示,其中的一個被隱藏。如果你想要把它找回來,使用強制:

public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     System.out.println("Data1="+((A)b).data); // like this 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

生產:

Data1=10 
Data2=20 
In A=10 
In B=20 

附:您可以在作業的任一側使用演員表:

public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     ((A)b).data *= 10; 
     System.out.println("Data1="+((A)b).data); 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

Data1=100 
Data2=20 
In A=100 
In B=20 

PPS。我發佈了這個教程,向你展示這門語言是如何工作的,但總的來說,它是而不是是一個好主意,它可以讓其他類可以直接讀寫的類中存在公共字段。見Why use getters and setters?

0

除非你犯了一個錯字,下面兩行基本一致:

System.out.println("Data1="+b.data); 
System.out.println("Data2="+b.data); 

這可能有助於想象這樣的對象:

A { 
    [A.data = 10]; <-- this is overridden and cannot be accessed directly 
    show1() => 10; 
    B { 
    B.data => 20; 
    show2() => 20; 
    } 
} 
0

你居然沒覆蓋方法....

`System.out.println(「Data1 =」+ b.data);

的System.out.println(「數據2 =」 + b.data);`

爲這兩條線「數據」值將被通過從類B. 的數據變量取出現在,類B擴展了A類,這意味着類A中的所有成員都將在類B中繼承。因此,變量i(類A)將繼承,並且在類B中我們有它自己的局部變量i ...... show1 )類的方法也將在類B中繼承。因此,通過使用類B的引用變量(b),我們可以訪問show1()方法以及show2()方法。

相關問題