BinaryTree 期望 Comparable,另一个实现 Comparable 的子类不起作用

BinaryTree expects Comparable, subclass of another which implements Comparable not working

我有一个通用抽象 class、BString,它希望其中一种类型实现 Comparable。另一个 class、NGram 扩展 BString,将 String 作为可比类型传递。最后的 class、BinarySearchTree 需要扩展 Comparable.

的键

为什么我无法创建以 NGram 作为键类型的 BinarySearchTree?我在下面包含了 class 声明,请注意虽然 BString 覆盖 compareTo,但 NGram 不会。

当我实际创建 BinarySearchTree 时,如代码的最后一行所示,我收到以下消息:

Bound mismatch: The type NGram is not a valid substitute for the bounded parameter <K extends Comparable<K>> of the type BinarySearchTree<K,V>

下面是代码。

public abstract class BString<Alphabet extends Comparable<Alphabet>> implements Iterable<Alphabet>, Comparable<BString<Alphabet>> {
protected FixedSizeFIFOWorkList<Alphabet> str;

}
public BString(Alphabet[] str) {
    this.str = new CircularArrayFIFOQueue<Alphabet>(str.length);
    for (int i = 0; i < str.length; i++) {
        this.str.add(str[i]);
    }
}

public class NGram extends BString<String> {
    public NGram(String[] str) {
        super(str);
    }
}

public class BinarySearchTree<K extends Comparable<K>, V>
    extends ComparableDictionary<K, V> {
    // The root of the BST. Root is null if and only if the tree is empty.
    protected BSTNode root;

    /**
     * Create an empty binary search tree.
     */
    public BinarySearchTree() {
        super();
        this.root = null;
    }
}

new BinarySearchTree<NGram,Dictionary<AlphabeticString, Integer>>()

您收到此错误是因为您已声明:

BinarySearchTree<K extends Comparable<K>, V>

当您使用NGram作为K时,预计会实现Comparable<NGram>。因为它没有实现 Comparable<NGram> 你会得到错误。

编辑

有关此问题和解决方法的更多详细信息:

当超级class实现Comparable<SuperClass>时,子class不能再次实现Comparable<SubClass>。这将意味着 subclass 两次实现相同的通用类型。 Java 不允许。

解决方法是在子class 中也实施Comparable<SuperClass>。在方法实现中,检查 subclass 类型并进行处理。根本不想实现 `Comparable 你有一个 class 层次结构。相反,使用比较器。

因此,要在当前情况下解决您的问题,请通过以下方式声明 BinarySearchTree 以允许 NGramK:

BinarySearchTree<K extends Comparable<? super K>, V> 

否则,删除 Comparable 并改用 Comparator。请注意,如果没有上述更改,您可以在构造 BinarySearchTree 时将 BString 用作 K,因为它实现了 Comparable<BString>.

您的 class NGram 实现 Comparable<BString<Alphabet>>(继承自 BString)。为了满足 BinarySearchTree 的类型参数 K 的边界要求,它需要实现 Comparable<NGram>。后者不是前者的子类型。

本质问题是BinarySearchTree的要求太严格了。为了比较两个 NGram 不需要 class 专门与自身进行比较。它足以与它自己的任何 superclasses 相媲美。准确地说,这个概念可以这样表达:

public class BinarySearchTree<K extends Comparable<? super K>, V>
        extends ComparableDictionary<K, V> // ...

当然,这也可能需要 ComparableDictionary 放松。