[英]Proper use of Comparable with generics
我在使接口以我想要使用泛型的方式工作時遇到了麻煩。
我有一個CRUD風格的界面來處理各種對象的數據訪問。 Comparable<?>
用於通過標識符獲取對象,因為對象可能具有不同類型的標識符:
public interface DataProvider<T> {
T create(T object);
T get(Comparable<?> id);
void update(T object);
void delete(T object);
}
現在想象一個需要訪問的此類(人為)對象Book
:
public class Book implements Comparable<Book> {
private ISBN isbn;
public int compareTo(Book other) {
return getIsbn().compareTo(other.getIsbn());
}
// ...
}
我想做的是這樣的:
public class BookDataProvider implements DataProvider<Book> {
public Book create(Book book) { ... }
public Book get(ISBN isbn) { ... }
public void update(Book book) { ... }
public void delete(Book book) { ... }
}
修改DataProvider
和/或Book
以允許get(ISBN)
編譯的最簡單方法是什么?
我已經提出了一些部分解決方案,但是我不確定哪一個是最佳的:
DataProvider
作為DataProvider<T, I extends Comparable<I>>
,但是這增加了額外的類型參數。 Identifiable
接口,使Book
實現它,並在DataProvider<T extends Identifiable<?>>
鍵入DataProvider
,但是然后我沒有實現get(ISBN)
的簽名。 理想情況下,我想限制DataProvider
僅具有一個類型參數。 我也對其他方法持開放態度。 謝謝。
使用具有可比性的專用getter方法的參數是不恰當的。 理想情況下,您的get方法不應適用於任何Comparable。 僅適用於ISBN等特定類型。 因此,我建議不要為可比較的泛型而苦苦掙扎,而應使用此類標識符的通用接口。
讓我們從部分選項中采用第二種方法並創建一個解決方案。 下面是我建議的代碼。
public class TestGenerics {
public static void main(String[] args) {
}
}
interface Identifiable<T extends Identifier> {
T getIdentifier();
}
interface Identifier {
}
class Book implements Comparable<Book>, Identifiable<ISBN> {
private ISBN isbn;
public int compareTo(Book other) {
return getIdentifier().compareTo(other.getIdentifier());
}
public ISBN getIdentifier() {
return null;
}
}
class ISBN implements Comparable<ISBN>, Identifier {
public int compareTo(ISBN o) {
return 0;
}
}
interface DataProvider<T extends Identifiable<? extends Identifier>> {
T create(T object);
T get(Identifier id);
void update(T object);
void delete(T object);
}
class BookDataProvider implements DataProvider<Book> {
public Book create(Book book) {
return null;
}
public void update(Book book) {
}
public void delete(Book book) {
}
public Book get(Identifier id) {
// TODO Auto-generated method stub
return null;
}
}
現在,這種方法是真正通用的,因為在頂層,您已經有了Identifiable&Identifier接口,這意味着每個Identifiable(例如book,pdf等)都必須具有一些Identifier(例如ISBN,bookNumber等)。
現在,您可以使用Book作為Identifiable和ISBN作為Identifier來實現此頂層層次結構。 這將是您的實施層。
然后,您為泛型中提到的Identifiable創建DataProvider接口。 它的get方法將以標識符作為參數,即如果DataProvider用於Book,則其get方法將用於ISBN。
現在,您在此處使用BookDataProvider實現DataProvider。 在此類中,您不會將ISBN作為參數,而是將標識符作為參數。 您可以在其中傳遞ISBN,因為它是一個標識符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.