2014-01-22 109 views
2

好吧,我從來沒有使用過泛型,並想知道我是否可以按照以下方式使用泛型。關於Java泛型和子類

讓我們假設我有這個類

public class ASuperClass { 
    public abstract void doSomething(String arg1, Integer arg2); 
} 

所以,如果我再擴展上面的類我會再有以下,在那裏我將不得不重寫DoSomething的與字符串和整數的參數列表。

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2){ 
     some code..... 
    } 
} 

現在,讓我們假設在我的子類,我也好覆蓋DoSomething的,但我需要在我的子類的附加字符串ARG。所以,我希望做的是有以下:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2, String arg3){ 
     some code... 
    } 
} 

上面雖然不會編譯,因爲我的子類沒有實現在基本定義的抽象簽名。所以,爲了讓它編譯,我當然可以這樣做:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2){} 

    public void doSomething(String arg1, Integer areg2, String arg3){ 
     here is my code...... 
    } 
} 

那麼,我究竟想要做什麼,你可能會問?我感興趣的是,是否有辦法「強制」類的任何子類,使用泛型作爲參數,實現基本抽象方法,而不管參數列表如何。因此,以下將編譯延長ASuperClass:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer areg2, String arg3){ 
     here is my code...... 
    } 
} 

public class AnotherSubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer areg2, String arg3, Integer arg4){ 
     here is my code...... 
    } 
} 

那麼,你能「仿製IZE」的基類ARG列表,以便上述兩個班將彙編?像下面的東西?我知道下面的語法是錯誤的,但是你可以使arg列表是通用的嗎?總的來說,我的想法是在人們擴展一些基本功能的應用程序中強制執行一致性。基本上確保ASuperClass的每個子類都有一個doSomething()成員函數,以確保跨子類的一致性(特別是方法命名),但是它的arg列表可能在每個子類中都不相同。

希望以上不是太混亂。有興趣知道這是否可能。

+0

這根本不可能。而仿製藥甚至無法進入畫面。你必須在子類中有兩種不同的方法。 –

回答

0

方法參數是方法的「簽名」,這是用來決定壓倒一切的一部分。爲了使子類覆蓋其基類中的方法,爲了實現其抽象基類的抽象方法或實現接口方法,必須匹配整個簽名(包括參數類型)。

如果您想參數列表可以帶可變數量的參數,你可以使用這個語法:

public abstract void doSomething(Object ... args); 

您可以覆蓋的方法,在子類中的簽名,你可以通過許多參數如你所願。這樣的設計決策的一些不幸的結果是

  • 你的參數現在是無類型 - 每種方法需要驗證它的參數,包括它們的類型列表,計算出發之前,和
  • 參數原始類型需要包裝在Object s - 原語需要裝箱或自動裝箱。
0
public class ASuperClass 
{ 
    public abstract void doSomething(Object ... args); 
} 

public class ASubClass extends ASuperClass 
{ 
    @Override 
    public void doSomething(Object ... args) 
    { 
     here is my code...... 
    } 
} 

這將允許兩個呼叫:doSomething(str1, int1)doSomething(str1, int1, str2, int2);

+0

這就是我所想的。那麼,這是否涵蓋了任何參數類型?比如我可以在子類: @Override 公共無效DoSomething的(字符串ARG1,ARG2整數,INT ARG3) { 這裏是我的代碼...... } 意義,將省略號對象.... args包裝原始類型? 謝謝 – tas2826

0

如果你定義了一個像這樣的抽象方法,它意味着實現這個抽象類的任何類型的對象都保證包含這個方法。

例如看這個代碼示例。

List<ASuperClass> list = new ArrayList<ASuperClass>(); 
list.add(new ASubClass()); 
list.add(new AnotherSubClass()); 

因此,我們創建一個ASuperClass類型的對象列表,然後將兩個對象添加到此列表中。這些對象是不同的類型,但它們都共享這個共同的父對象。這意味着我們可以保證他們將響應ASuperClass類型的所有方法簽名。

for(ASuperClass obj : list) 
{ 
    obj.doSomething("parm1", 1); 
} 

如果你讓子類型確定參數列表,那麼這將打破這個。我們知道有一種叫doSomething的方法,但它對我們來說沒用,因爲無法知道參數應該是什麼。

正如其他人所說的那樣,這樣做有點怪異。

public abstract void doSomething(Object ... params); 

雖然這是完全正確的,但我確定沒有人在他們正確的心態會建議實際做到這一點。它唯一的建議是完整的。

如果另一方面您想要可變數量的相同類型的參數,那麼您可以更安全地使用它。

public abstract void doSomething(String parm1, Integer parm2, String ... params); 

在這種情況下,您將始終需要一個字符串,一個整數,然後是可變數量的字符串。這相當於這樣做。

public abstract void doSomething(String parm1, Integer parm2, String[] params);