2017-08-30 102 views
1

在Java中,與它引用 的實例相關的對象引用如何實現? 我遇到了一些非常棘手的問題,並想深入瞭解它。在下面的場景中,子類的shine()重寫了超類的(這是正常的),但name屬性是超類的名稱,儘管在子類上調用了NEW(我發現這很奇怪!)有人會幫我瞭解這個?繼承場景中引用和對象之間的關係

class Father { 
    public String name = "John Senior"; 
    public void shine() { 
     System.out.println(name + "'s shining"); 
    } 
} 

//Subclass 
class Son extends Father { 
    public String name = "John Junior"; 
    public void shine() { 
     System.out.println(name + "'s shining"); 
    } 
} 

//Demo Class 
class Test { 
    public static void main(String[] args) { 
     Father f1 = new Son(); 
     System.out.println(f1.name); 
     f1.shine(); 
    } 
} 

//program output 

/*John Senior 
John Junior's shining */ 
+2

此代碼不會編譯。 'main'中沒有's1'。也張貼輸出。 –

+0

@AhhijitSarkar你是對的。這是一個錯字。 – makassi

回答

2

變量在Java中不是多態的;他們不會互相推翻。而方法是多態的。因此,上述行爲。 如果您想要打印超類成員,請使用super關鍵字。

1

你觀察到的行爲起初可能並不直觀,但實際上,因爲@ shaggy-d提到過,變量不是多態的。讓我解釋一下,發生了什麼,但首先忘記shine()方法,讓我們先了解name

這裏是您的main方法中的一些其它實例中,用適當的輸出和一個解釋:

實施例1:

public static void main(String[] args) { 
    Object f1 = new Son(); 
    System.out.println(Father.class.cast(f1).name); 
    System.out.println(Son.class.cast(f1).name); 
} 

輸出:

John Senior 
John Junior 

你確實隱藏式f1變量,並說Hi Java let's treat at within the scope as對象. So now when you want to get the名稱, you actually need to tell Java what it should think of the object, i.e., is it a父親or a兒子. Depending on your decision, Java picks what要使用的名稱「屬性」。

例2:

public static void main(String[] args) { 
    Son f1 = new Son(); 
    System.out.println(Father.class.cast(f1).name); 
    System.out.println(Son.class.cast(f1).name); 
    System.out.println(f1.name); 
} 

輸出:

John Senior 
John Junior 
John Junior 

正如預期的那樣,當你告訴Java中的對象應該爲你的範圍內Son進行治療,它解決了從兒子name(如果沒有明確地鑄造其他

現在回到你的shine()方法。再次作爲@ shaggy-d提到,方法s是多形的。因此,在調用對象的方法時,Java會確定對象層次結構中「最低」的可用實現並執行該方法。

1

enter image description here

我會嘗試用一個圖來解釋一下:當我們實例Son有它的好,在創建它創造的Father一個實例:在引擎蓋下,兒子的構造函數被調用之前 - 父親構造函數也被調用,因此Son的新實例也具有來自它所擴展類的對象的上下文。現在

,因爲你宣佈F1Father類型,當f1.name評估,它正在查找在Father的背景下 - 這就是我們如何讓「資深」。

但是,當方法被調用時,多態性「踢進」,被調用的方法是屬於Son(並且覆蓋了Father的方法)的方法。這是因爲我們分配了new Son()f1

+1

感謝您的乾淨解釋。我希望確認在任何時候我們創建一個Son實例時,都會隱式地調用Father的無參數構造函數。 – makassi