2014-02-18 198 views
0

的影響我有以下四大類問題:Java繼承和覆蓋方法 - 改性

class X { 
    void a() { 
     b(); 
     c(); 
    } 
    void b() { 
     System.out.println("b from class X"); 
    } 
    private void c() { 
     System.out.println("c from class X"); 
    } 
} 

class Y extends X {  
    void b() { 
     System.out.println("b from class Y"); 
    } 
} 

class Z extends Y {  
    void b() { 
     System.out.println("b from class Z"); 
    } 
    void c() { 
     System.out.println("c from class Z"); 
    }  
} 


public class Main { 

    public static void main(String[] args) { 
     Y y = new Z(); 
     y.a(); 
    } 

} 

請不要評論類的合理性,它只是一個例子。我也嘗試通過使用eclipse調試器的方法來跟蹤JVM的流程,但是通過這些方法的步驟在某些點上有點快。

我已經有了,那

Y y = new Z(); 

創建在Z類的新實例,並將其分配給Y類的參考。由於Z中沒有構造函數,因此編譯器會在每個超類中查找是否存在構造函數,如果沒有構造函數,則使用該對象類的構造函數。 此後,

y.a(); 

方法被調用。在類Z中沒有這樣的方法,所以我們再次結束於方法a存在的類X並執行它。 首先我們執行該方法c中調用後使用它,因爲你的目標是Z類的一個實例,並且該方法B在Z類覆蓋導致輸出

b from class Z. 

方法B(在方法) 。由於我們的實例仍然從Z類的實例,並存在在這個類中的方法c您能想出的想法,輸出

c from class Z 

會發生。但這不是真的,因爲類X中的c方法是一種私有方法。由於它是私有的,它不能被繼承到子類(它甚至不能被看到)。所以不需要任何從X繼承的類也有c方法。是不是真的,因爲從方法a調用c導致在類X中調用c方法而不是在類Z中調用?

所以簡述: 是我從上面的解釋正確還是缺少什​​麼?我只是有點糊塗了,雖然我的實例是從類Z,從裏面方法導致以下結果調用方法C:

b from class Z 
c from class X 

我的第一個想法是,輸出的樣子:

b from class Z 
c from class Z 

希望我以某種方式現在可以幫助我的方式描述問題。謝謝你的回覆。

+0

注意:你說,「編譯器在每個超類中查找是否存在構造函數」。所有這些類都有構造函數。如果源代碼中沒有一個,編譯器將生成一個默認的無參數構造函數,該構造函數僅調用超類構造函數。 –

回答

1

這是事實,這將是印:

c from class X 

因爲cprivateX,和private methods aren't inherited in Java

子類不繼承其父類的私有成員。但是,如果超類具有訪問其專用字段的公共或受保護方法,那麼這些也可以由子類使用。

因此,即使X的方法a調用c方法,它只能調用Xc方法。在Z中存在另一種稱爲c的方法並不重要; a只能撥打X中的c方法。 c方法Z確實不是覆蓋c方法X,因爲它是私人的。

要調用Zc方法的唯一方法是有一個Z引用並直接調用它,因爲它不是私有的。

Z z = new Z(); 
z.c(); 

,它將打印

c from class Z 
+0

好的,太好了。感謝您的快速回答。 – ROT13

0

是的你是對的。類X在方法的():從類X

void a() { 
    b(); 
    c(); 
} 

僅方法C()是可見的。這是因爲從X班內部看不到Z班。

0

編譯器可以靜態解析C()其德X類中的私有方法,沒有必要動態清晰度,這意味着沒有多態私人方法的行爲。

認爲c()是實現一個()的一部分,它的一個實現細節,想象一下你在X中將名稱從c改爲c1,你期望改變一個不同的行爲私人方法名稱在一個類?,語言必須確保這樣的變化不會對孩子有影響。