2009-02-04 38 views
1
class Super { 

     public void anotherMethod(String s) { 
      retValue(s) 
     } 


     public String retValue(String s) { 
      return "Super " + s; 
     } 

    } 

    class Sub extends Super { 

     public void anotherMethod(String s) { 
      retValue(s) 
     } 

     public String retValue(String s) { 
      return "Sub " + s; 
     } 

    } 

如果想在主,如何繞過繼承

Super s = new Sub(); 
s.anotherMethod("Test"); 

輸出將是,分測試

你能任何人幫助我告訴如何獲得輸出超級測試在主要給定的序列。

讓我解釋一下我爲什麼要這樣,說我有有方法測試(一類),它可以通過子類重寫的,在某些情況下,我希望被覆蓋的測試()和有些情況下,我想要超類本身的測試(),有很多方法可以做到這一點,最好的建議將是有幫助的。

回答

7

每當我發現自己問(或被問)這樣的問題,我知道,明確地說,我在我的設計和/或我的對象定義中犯了一個錯誤。回到你的對象層次結構並檢查,仔細檢查和三重檢查每個繼承關係代表一個「IS-A」,而不是「HAS-A」或者更弱的東西。

10

爲什麼你想這樣做?

多態性的全部意義就是調用正確的方法,而不需要知道你有哪種類型的實例...

0

從子類可以調用super.anotherMethod(「BLA」),但是你不能在你的主要方法中訪問超類的方法 - 這會違背使用子類的整個想法。

0

s的運行時類型爲Sub,所以您只能在該類上調用方法。

2

你會去的路線:

Super s = new Super(); 
s.anotherMethod("Test"); 

...但是,這將擊敗繼承的目的,如果你還需要什麼子的了。你可以像下面那樣破解它,但這似乎是一種不合時宜的方式。

class Sub extends Super { 

    public String anotherMethod(String s, boolean bSuper) { 
     if(bSuper) 
      return super.retValue(s); 
     else 
      return retValue(s); 
    } 

    public String retValue(String s) { 
     return "Sub " + s; 
    } 

} 
0

雖然我與其他海報,這是不是世界上最好的想法一致,我相信它可以擺弄的一點點來完成。

如果你的子類的定義爲:

class Sub extends Super { 

     public void anotherMethod(String s) { 
      retValue(s) 
     } 

     public void yetAnotherMethodString s) { 
      super.retValue(s) 
     } 

     public String retValue(String s) { 
      return "Sub " + s; 
     } 

    } 

,然後調用你的主要新方法,你就可以打印出「超級測試」。

似乎不是一個很好的計劃壽。如果你想從一個子類訪問父功能,那麼不要重寫你的父方法,只需寫一個新的!

+0

假設我們不能修改子類或調用者。 – 2009-02-04 12:02:51

+0

所以你不能修改子類?現有的方法呢? – chillysapien 2009-02-04 14:34:50

-1

你能誰能幫我在講述如何 獲得輸出「Super Test」與 給出序列main

  • 不要擺在首位覆蓋anotherMethod()retValue()Sub

  • S中ub.anotherMethod(),返回super.retValue(s)而不是retValue(s)

0

我hesistant張貼此作爲一個答案,因爲這個問題是很可怕的 - 但靜態方法會做大概什麼OP似乎想。具體來說,它們在變量的編譯時聲明類中解析,而不是在運行時在該變量中保存的實例的類上解析。

所以修改原來的例子:

class Super {
public static void staticMethod(String s) { System.out.println("Super " + s); } }

class Sub extends Super { 

    public static void staticMethod(String s) { 
     System.out.println("Sub " + s); 
    } 

} 

public static void main(String[] args) { 

    Super s = new Sub(); 
    s.staticMethod("Test"); 

} 

然後主()將打印出 「超級測試」。

但仍然不要這樣做直到你明白你爲什麼想要,並且你意識到你正在引入子類,然後無償地圍繞它們在那裏工作。例如,大多數IDE會將上面的例子標記爲很多警告,說明你不應該在實例變量上調用靜態方法(比如Super.staticMethod("Test")而不是s.staticMethod("Test")),正是出於這個原因。

3

讓我解釋一下我爲什麼要這樣, 說我有有方法 測試(A類)和它可以通過 子類重寫的,有些情況下,我想 被覆蓋的測試()和在某些情況下 測試()的超類本身,有 有很多方法可以做到這一點,它將是 有用,如果有人能成爲最好的 解決方案。

如果你的子類覆蓋test()那麼它將覆蓋測試() - 這是對象繼承的全部意義。您只需調用對象上的方法,根據對象的運行時類將其動態解析爲適當的實現。這就是多態鍵入的美妙之處,事實上,調用者根本不必知道任何這些,而子類決定了他們的行爲與超類的不同之處。

如果您有時希望它充當其超類方法,並且有時希望它充當其子類方法,那麼您需要提供執行此操作所需的上下文。你可以定義兩種測試類型的方法;一個永遠不會被覆蓋,因此總是返回超類的行爲(你甚至可以用final來標記定義以確保它沒有被覆蓋),以及你的正常的一個,它被子類適當地覆蓋。或者,如果有一些上下文信息可用,您可以讓子類決定如何處理;例如,它們的實現可以檢查某些proeprty,並根據該決定是決定是調用super.test()還是繼續執行它們自己的重載實現。

你選擇哪一個取決於你的main方法(即調用者)或(子)類對象本身是否處於判斷是否應該調用超類的方法的最佳位置。

但絕不能重寫一個方法,並期望它有時魔術般不會被覆蓋。

0

您不能直接修改Sub或Super嗎?如果你能控制哪些子的實例使用,你可以這樣做:

Super sub = new Sub() { 
    @Override 
    public String retValue() { 
    // re-implement Super.retValue() 
    } 
}; 
otherObject.use(sub); 

當然這需要你擁有或能夠重現Super.retValue(源代碼),此方法不使用任何你無法從匿名孩子訪問的東西。如果API設計的這麼糟糕,那麼你可以考慮把它改爲其他的東西。