簡體   English   中英

繼承與泛型相媲美

[英]Inheriting Comparable with generics

試圖設計一個超類,確保所有子類本身都是Comparable

/**
 * A base class implementing Comparable with itself by delegation.
 * @param <T> - The type being wrapped.
 */
static class Distinct<T extends Comparable<T>> implements Comparable<Distinct<T>> {
    final T it;
    public Distinct(T it) {
        this.it = it;
    }
    @Override
    public int compareTo(Distinct<T> o) {
        return it.compareTo(o.it);
    }
}
/**
 * A set of distinct items.
 *
 * @param <T>
 */
static class ThingHolder<T extends Comparable<T>> {
    final Set<T> things;
    public ThingHolder() {
        this.things = new TreeSet<>();
    }
}
/**
 * A sample real thing.
 */
static class Thing extends Distinct<String> {
    public Thing(String it) {
        super(it);
    }
}
// This doesn't work - Why?
final ThingHolder<Thing> yz = new ThingHolder<>();

我得到的錯誤是:

com/oldcurmudgeon/test/Test.java:[70,22] error: type argument Thing is not within bounds of type-variable T
  where T is a type-variable:
    T extends Comparable<T> declared in class ThingHolder

為什么這不起作用? 可以嗎?

  1. 如果將類型參數X傳遞給ThingHolder它必須是Comparable<X>的子類型(通過ThingHolder的類聲明)。
  2. 因此,如果將Thing類型傳遞給ThingHolder它必須是Comparable<Thing>的子類型。 (根據之前的陳述,將Thing替換為X
  3. Thing擴展了Distinct<String> ,因此實現了Comparable<Distinct<String>> (通過Thing的類聲明)。
  4. ThingDistinct<String>類型Distinct<String> - 盡管它是一個子類型 - 因此類型匹配失敗。

你可以通過調整ThingHolder的類聲明來解決這個ThingHolder ,如下所示:

class ThingHolder<T extends Comparable<? super T>> {
    ...
}

一些研究和抨擊提出了這個建議

通常,如果您的API只使用類型參數T作為參數,則其使用應該利用較低的有界通配符(?super T)。

一些修補(添加? super T )略微放松限制葉:

/**
 * A set of distinct items.
 *
 * Don't like the <?> in there but a <T> is not accepted.
 *
 * @param <T>
 */
static class ThingHolder<T extends Comparable<? super T>> {

    final Set<T> things = new TreeSet<>();

}

final ThingHolder<Thing> holder = new ThingHolder<>();

這對編譯器來說是可以接受的。

一般我不喜歡用? 為了填補空白,因為它通常允許過多,但在這種情況下,我會留下它。

只需將ThingHolder類簽名更改為:

static class ThingHolder<T extends Comparable> {
       ...    
}

即從Comparable刪除<T> ,沒有必要。

class ThingHolder<T extends Comparable<T>>聲明事物 T必須與自身相當,但class Thing extends Distinct<String>不是。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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