[英]About Java generics and subclasses
好的,我從來沒有大量使用過泛型,並且想知道是否可以通過以下方式使用它們。
假設我有這堂課
public class ASuperClass {
public abstract void doSomething(String arg1, Integer arg2);
}
因此,如果再擴展上述類,則將具有以下內容,其中將被迫使用String和Integer的參數列表覆蓋doSomething。
public class ASubClass extends ASuperClass{
@Override
public void doSomething(String arg1, Integer arg2){
some code.....
}
}
現在,假設在我的子類中可以重寫doSomething,但我的子類中需要一個額外的String 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......
}
}
所以,我到底想做什么呢? 我感興趣的是,有沒有一種方法可以使用泛型作為arg來“強制”類的任何子類,以實現基本的抽象方法,而與arg列表無關。 這樣就可以編譯擴展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......
}
}
那么,您能否“泛化”基類的arg列表,以便可以編譯以上兩個類? 像下面的東西? 我知道下面的語法是錯誤的,但是您可以使arg列表通用嗎?
public class ASuperClass {
public abstract void doSomething(<?>);
}
總的來說,我的想法是在人們正在擴展某些基本功能的應用程序中實現一致性。 基本上確保ASuperClass的每個子類都有一個doSomething()成員函數,以確保子類之間的一致性(尤其是方法命名),但是每個子類的arg列表可能有所不同。
希望以上內容不會太混亂。 有興趣知道這是否可能。
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);
方法參數是方法“簽名”的一部分,用於決定覆蓋。 為了使子類重寫其基類中的方法,實現其抽象基類的抽象方法或實現接口方法,整個簽名(包括參數類型)必須匹配。
如果您希望參數列表采用可變數量的參數,則可以使用以下語法:
public abstract void doSomething(Object ... args);
您可以在子類中使用此簽名覆蓋方法,並且可以根據需要傳遞任意數量的參數。 此設計決定的一些不幸后果是:
Object
- 基本類型需要裝箱或自動裝箱。 如果定義這樣的抽象方法,則意味着實現該抽象類的任何類型的對象都可以保證包含該方法。
例如,看下面的代碼示例。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.