简体   繁体   中英

implementing a java interface and using generics

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?

Because

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

In your class declaration, the generic type is a type declaration, something you can reuse later in the class body. In the interface you are implementing, it is a type argument argument. In other words, you are saying my class implements this interface with this type. you have to give it a specific type. It doesn't make sense to say Key extends Comparable... as a type argument.

The Java Language Spec has more details

The type parameter section follows the class name and is delimited by angle brackets.

and in the section for Superclasses

If the TypeDeclSpecifier is followed by any type arguments, it must be a correct invocation of the type declaration denoted by TypeDeclSpecifier, and none of the type arguments may be wildcard type arguments, or a compile-time error occurs.

The other answer is correct, but I just wanted to add the fix .

Basically, you pass the type parameters onto the superclass/interface, like this:

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

Also please adhere to java naming standards and use single letters for your generic parameter babes. Using words is too easily confused with being a class name.

The keywords extends and super define constraints on generic types. It only makes sense to constrain type parameters coming in , not type parameters going out .

The situation is analogous to method parameters. When declaring a method, you use:

public void foo(Bar bar) { 
    //          ^ the type is a constraint on bar 
}

(The "constraint" is that any value passed to bar must be Bar or one of its subtypes.)

However, you call the method with just:

foo(someBar);
//  ^ no constraint specified here

That is, it doesn't make sense to constrain the type of a variable where it's used. (That was already done in the declaration.)

In your class declaration it's more confusing because a generic type is both declared and another one is used on the same line. The interpretation of that line is:

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

Of course, just like with variables, the incoming "type" for Key has to be compatible with the types required where it's used, which is why you have to duplicate the constraints in the declaration of BSTImpl .

(This symmetry also illustrates what generics really are: they're higher-order type constraints, that is a way to specify "types of types".)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM