0

I have a java interface called BST (short for binary search tree) which has generic types Key,Value where Key extends Comparable.I defined it as below.

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();

}

Now I want to define an implementation of the above interface.I tried this

public class BSTImpl<Key extends Comparable<Key> ,Value>  implements BST<Key extends Comparable<Key>,Value> {

... 

}

The above definition causes an error message in eclipse IDE ..The extends token after implements BST<Key seems to be the culprit

Syntax error on token "extends", , expected

If I omit the "extends" token from the definition (as given below),the error goes away, and I can get eclipse to generate the unimplemented methods correctly

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;
    }
}

Why does the extends token cause an error in the first place? can someone please explain?

4

3 回答 3

5

因为

public class BSTImpl<Key extends Comparable<Key> ,Value>  implements BST<Key extends Comparable<Key>,Value> {
                    ^ type declaration                                   ^ type argument

在您的类声明中,泛型类型是一种类型声明,您可以稍后在类主体中重用它。在您正在实现的接口中,它是一个类型参数参数。换句话说,你是说我的类用这种类型实现了这个接口。你必须给它一个特定的类型。Key extends Comparable...作为类型参数说是没有意义的。

Java 语言规范有更多细节

类型参数部分跟在类名之后,并由尖括号分隔。

超类部分

如果 TypeDeclSpecifier 后跟任何类型参数,则它必须是对由 TypeDeclSpecifier 表示的类型声明的正确调用,并且任何类型参数都不能是通配符类型参数,否则会发生编译时错误。

于 2013-10-07T16:04:44.463 回答
1

另一个答案是正确的,但我只是想添加fix

基本上,您将类型参数传递给超类/接口,如下所示:

public class BSTImpl<Key extends Comparable<Key>, Value> implements BST<Key, Value> {
    ... 
}

还请遵守 java 命名标准,并为您的通用参数宝贝使用单个字母。使用单词很容易与类名混淆。

于 2013-10-07T16:19:04.400 回答
1

泛型类型的关键字extendssuper定义约束。只有限制类型参数传入才有意义,而不是类型参数传出

这种情况类似于方法参数。声明方法时,您使用:

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

(这种对称性也说明了泛型的真正含义:它们是高阶类型约束,这是一种指定“类型的类型”的方式。)

于 2013-10-07T16:20:14.290 回答