我正在嘗試學習如何使用泛型,但是我在實作工廠模式方面遇到了困難。我希望我的 DataFactory 介面有一個方法來回傳一個擴展資料的類的物件。我相信下面的代碼會起作用,但我很難理解一些東西。有沒有辦法避免在 DataFactory 介面中顯式指定第二種型別?訊息擴展了 Data<String>,所以如果 T 擴展了 Data<U>,不應該已經暗示了 U 嗎?
資料類:
public abstract class Data<T> {
private final long id;
private final T content;
private final User sender;
...
}
訊息類:
public class Message extends Data<String> {
...
}
資料工廠介面:
public interface DataFactory<T extends Data<U>, U> {
T newInstance(U content, User sender);
}
訊息工廠類:
public class MessageFactory implements DataFactory<Message, String> {
@Override
public Message newInstance(String content, User sender) {
return new Message(content, sender);
}
}
為什么我不能只寫:
public class MessageFactory implements DataFactory<Message>
如果這不是一個措辭良好的問題,我很抱歉,我不確定如何表達它。最初我不想向類本身添加型別引數,只是向方法添加型別引數,但是我在嘗試使其作業時遇到了更多問題。我什至不確定我是否正確地實施了這一點。任何幫助,將不勝感激。
uj5u.com熱心網友回復:
因為型別系統本身不知道,在一般情況下,你不會寫GenericData<T> extends Data<T>. 在這種特定情況下,您的Message類具有用于泛型型別的特定類,但您可以提供其他沒有的引數。
uj5u.com熱心網友回復:
即使 OP 已經選擇了一個答案,我還是想分享更多的相關資訊,以幫助其他人來這里尋找答案。
為什么要使用泛型?
首先,我們首先需要了解使用泛型的原因是什么。泛型型別引數為您提供了一種在不同輸入中重用相同代碼的方法。例如,您可以使用通用代碼來處理字串集合或具有相同代碼的小部件集合。在泛型之前,我們過去處理類似情況的方式是通過強制轉換物件。為簡化起見,讓我們使用 OP 示例并使Data類成為非抽象類。
public void doSomethingWithThisInput (Object o) {
if (o instanceof MyClass) {
MyClass myCls = (MyClass) o;
// do something here
}
}
如果您在泛型之前處理過 Java Collection,您就會知道這曾經是多么痛苦。舊方法的部分問題在于,在許多情況下,您沒有在開發程序中發現轉換問題。這些案例中幾乎 100% 是在運行時發現的,每個人都同意這是非常糟糕的。對于泛型,這些物件不兼容問題是在編譯時發現的。
泛型用例
您想要使用泛型的主要原因是在類中創建類似“事物”的集合。在 Java 語言中隨處可見這樣的示例Set,包括List、Map、 等。
public abstract class Data<T> {
private T content;
// other methods and attributes omitted;
}
使用這樣的類,您可以Data通用地參考物件的內容。資料內容實際上可以是任何內容:一個Email物件、一個File物件,或者只是一個String. 顯然,這里的意圖是如果你有一個資料內容的集合,每個物件應該是相同的型別。創建不同內容的集合毫無意義,而且實際上適得其反。
職業教育學院
這可能是您需要學習如何正確使用泛型的最重要的一課。**PECS** 是代表 Producers Extend Consumers Super 的首字母縮寫詞。這是什么意思?我能給你的最佳答案可以在這里找到 [https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super][1]。該鏈接指向此處關于 PECS 的 SO 的答案。附加資源
Oracle Java 課程:泛型
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/334462.html
