我有一个名为BST的java接口(二进制搜索树的简称),它有通用类型Key,Value,其中Key扩展为Comparable。我将其定义如下。
public interface BST<Key extends Comparable<Key>,Value> {
public void put(Key key,Value value);
public Value get(Key key);
public void delete(Key key);
public Iterable<Key> keys();
}
现在我想定义上述接口的实现。我试过这个
public class BSTImpl<Key extends Comparable<Key> ,Value> implements BST<Key extends Comparable<Key>,Value> {
...
}
以上定义在eclipse IDE中导致错误消息。extends
之后的implements BST<Key
令牌似乎是罪魁祸首
令牌“extends”的语法错误,预期
如果我从定义中省略了“extends”标记(如下所示),则错误消失,我可以通过eclipse正确生成未实现的方法
public class BSTImpl<Key extends Comparable<Key> ,Value> implements BST<Key ,Value> {
@Override
public void put(Key key, Value value) {
// TODO Auto-generated method stub
}
@Override
public Value get(Key key) {
// TODO Auto-generated method stub
return null;
}
@Override
public void delete(Key key) {
// TODO Auto-generated method stub
}
@Override
public Iterable<Key> keys() {
// TODO Auto-generated method stub
return null;
}
}
为什么extends token首先会导致错误?有人可以解释一下吗?
答案 0 :(得分:5)
由于
public class BSTImpl<Key extends Comparable<Key> ,Value> implements BST<Key extends Comparable<Key>,Value> {
^ type declaration ^ type argument
在类声明中,泛型类型是一个类型声明,您可以稍后在类体中重用它。在您正在实现的接口中,它是一个类型参数参数。换句话说,您说我的类使用此类型实现此接口。你必须给它一个特定的类型。将Key extends Comparable...
称为类型参数是没有意义的。
Java Language Spec has more details
类型参数部分在类名后面,并由分隔符组成 尖括号。
如果TypeDeclSpecifier后跟任何类型参数,则必须是 正确调用由表示的类型声明 TypeDeclSpecifier,并且所有类型参数都不是通配符类型 参数,或发生编译时错误。
答案 1 :(得分:1)
另一个答案是正确的,但我只是想添加修复。
基本上,您将类型参数传递给超类/接口,如下所示:
public class BSTImpl<Key extends Comparable<Key>, Value> implements BST<Key, Value> {
...
}
另外请遵守java命名标准,并为您的通用参数宝贝使用单个字母。使用单词很容易与作为类名混淆。
答案 2 :(得分:1)
关键字extends
和super
定义泛型类型的约束。只有在 中约束类型参数才有意义,而不是 out 的类型参数。
情况类似于方法参数。声明方法时,使用:
public void foo(Bar bar) {
// ^ the type is a constraint on bar
}
(“约束”是传递给bar
的任何值必须是Bar
或其子类型之一。)
但是,您只需使用以下方法调用该方法:
foo(someBar);
// ^ no constraint specified here
也就是说,限制使用它的变量的类型是没有意义的。 (这已在声明中完成。)
在你的类声明中,它更令人困惑,因为声明了泛型类型,并且在同一行上使用了另一个类型。该行的解释是:
class BSTImpl<Key extends Comparable<Key>, Value>
// ^ a constraint on the types that can be passed to Key
implements BST<Key, Value>
// ^ here we're passing Key to another generic type
当然,就像变量一样,Key
的传入“类型”必须与使用它所需的类型兼容,这就是为什么你必须复制声明中的约束< / {>的BSTImpl
。
(这种对称性也说明了泛型的真正含义:它们是高阶类型约束,这是指定“类型类型”的一种方式。)