2015-08-21 128 views
8

重載是好的。但是如果我們考慮到我們有兩個對象ObjectA和ObjectB 。兩者都有「id」和「name」變量。我想寫一個方法(在第三類),它返回給定對象的名稱。寫入重載函數使我重複代碼。這是一個好習慣嗎? 不是更好地使用泛型函數嗎?使用泛型方法替代重載?

所以,我知道我可以寫一個重載函數,像這樣:

public String getInfo(ObjectA o){ 
    if(o.getId()!=1) return o.name; 
    return ""; 
} 
public String getInfo(ObjectB o){ 
    if(o.getId()!=1) return o.name; 
    return ""; 
} 

它工作正常。 但兩個功能都是一樣的!唯一的區別是事實,他們需要不同類型的論點。因爲它們看起來一樣,是不是違反了DRY規則? 我試圖編寫簡單的通用方法,但IDE將it.getId和that.name()標記爲錯誤,並建議將它轉換爲((ObjectA)).getId()或((ObjectB)that).getId )。我不是在該行」 T即= clazz.cast(O);? 我做錯了嗎?

public <T> String getInfo(Class<T> clazz, Object o) { 
       T that = clazz.cast(o); 
       if (that.getId()!=1) return that.name; 

      return ""; 
     } 

一般來說,我想知道,如果我的想法是可行的。如何能做到了我修復了我的錯誤?更重要的是,這是一個好主意嗎?或者更好地簡單地寫入重載功能?

+11

一個典型的解決方案是,確保對象A和對象B都實現一個聲明hasName和hasId方法的接口。 –

+0

鑑於'T'被擦除爲'Object',因爲'Object.getId()'不是實際的方法,所以上面的代碼不會被編譯。正如其他人所建議的那樣,你需要有一個通用的接口來定義'getId'。 –

+0

@AndyTurner類型擦除不會在這裏輸入圖片,它是純粹的類型代數。 'T'的_upper bound_是'Object'。擦除的後果只有在運行時纔會發生(編譯時在某些退化的情況下,只是由於Java中擦除的具體扭曲)。 –

回答

22

這兩種想法都不好,你的ObjectAObjectB類應實現一個通用接口,該接口定義了定義getId()getName()方法。

然後你就可以逃脫了一個方法:

public String getInfo(Interface o){ 
    if(o.getId()!=1) return o.getName(); 
    return ""; 
} 
+3

或者只是'getInfo()'是一個接口上的默認實現方法? – Kevin

+0

@Kevin我沒有指定將單個方法放在哪裏;)但是我很可能不會像這樣使用默認方法(儘管目前還不清楚「case」是什麼)。這段代碼看起來非常平凡,可以通過一個「空白」接口輕鬆解決。 – Kayaman

18

您的情況是編程接口的一個很好的選擇。創建接口並移動常用方法。

public String getInfo(InterfaceAB in){ 
    if(in.getId()!=1) return in.getName(); 
    return ""; 
}