2009-06-23 61 views
33

這裏工作的Java代碼Java可以在其他對象中調用父類重寫方法,但不能使用子類型?

class Cup { 
    public String sayColor() { 
     return "i have a color ."; 
    } 
} 

class TCup extends Cup{ 
    public String sayColor(){ 
     System.out.println(super.getClass().getName()); 
     return super.sayColor()+"color is tee green."; 
    } 
} 

class MyTCup extends TCup { 
    public String sayColor(){ 
     System.out.println(super.getClass().getName()); 
     return super.sayColor()+"but brushed to red now!"; 
    } 
} 
class Test { 
    public static void main(String[] args) { 
     Cup c = new MyTCup(); 
     System.out.print(c.sayColor()); 
    } 
} 

並運行測試類印刷品

MyTCup 
MyTCup 
i have a color .color is tee green.but brushed to red now! 

問題1: 在運行時,對象C的類型是MyTCup,但它總是可以調用超級方法。在初始化對象後,MyTCup中的內存中是否有方法堆棧,然後可以在運行時像代碼一樣調用?

問題2: 無法在其他對象中調用超級方法。據我所知,C++可以隨時強制轉換爲調用父級方法。爲什麼java這樣設計?

+1

你應該接受答案,一旦你滿意它:) – 2013-08-26 11:06:13

回答

65

你不能在其他對象中調用super方法 - 這會違反封裝。整個觀點是對象控制着重寫的方法。例如,您可以重寫集合的add方法以在某些情況下拋出異常,以確保只有「有效」項被添加到集合中。如果調用者可以通過演員繞過它,那將毫無意義!

對象自己調用super.foo()的唯一原因是通過使用父實現來啓用一個調用。這取決於課程中的代碼,以確保它只能做到這一點。同樣,如果集合取代add,它將不得不有一些方式將驗證的項目添加到集合,這將與super.add()做。

注意,出於同樣的原因encapuslation的,你可以只打電話你的父母實現,而不是祖父母執行 - 因此super.foo()是有效的,但super.super.foo()不是。

+0

參見http:// stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java(你的回答非常好)。 – 2009-06-23 14:32:46

+0

然後看看那個......我用了同樣的例子:) – 2009-06-23 14:38:02

1

1:

你的問題不太清楚。 「在運行時像代碼一樣調用」是什麼意思?如果你問實例c如何知道它的超類是什麼,那麼是的,類層次結構存儲在內存中,並且可以由虛擬機訪問。

2:

的Java實際上沒有讓你投一個實例其父。只是調用實例上的方法總是使用實例的實際類,而不是它的編譯時類。即在Java中,所有的方法都是在C++中被稱爲「虛擬」的。爲什麼這個決定我不知道。

編輯:其實喬恩斯基特解釋了非常漂亮的,爲什麼你不能調用父類的方法在子類的實例,所以現在我:-)知道。

0

您可以在子類中定義一個新的幫助器方法,這樣您就不會覆蓋原來的 - 調用 - 它可以調用超級方法或不調用,這取決於您想要的。

0

其實你可以,但你必須使用一種方法,所以它只會對你的代碼有效。
在超類中,添加參數「類」的方法,像:

public String sayColor(Class classFilter){... 

現在,在每個覆蓋,您檢查是否當前子類是指定的過濾器的一個如:

if(TCup.class!=classFilter)return super.sayColor(classFilter); 
return "some text for TCup only"; 

我以獨家方式編碼。你可以添加更多的參數,或者與空值進行比較,這樣你就可以將結果加入超類,用你的創造力:)

相關問題