簡體   English   中英

關於Java泛型和子類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM