0

I am designing an implementation of a BinarySearchTree, although I am stuck with an issue that I have not encountered before. I also have little understanding of how to fix this:

The type K is not a valid substitute for the bounded parameter <K extends Comparable<? super K>> of the type BST<K,V>

This is the error I get after creating an abstract class named BST<K extends Comparable<? super K>, V> and then having another class that extends this named RectangleBST<K,V> . So RectangleBST<K,V> extends BST<K,V> but I get the error when I use BST<K, V>.

One solution was to use extends BST<Integer, Rectangle>, although would that mean that I have now inherited the methods specifically for a Key of Integer type and a Value of Rectangle type?

Another may be to have the comparable in the RectangleBST instead, although I believe that my plan is to compare keys in BST rather than RectangleBST?

rgettman
  • 176,041
  • 30
  • 275
  • 357
dan
  • 347
  • 2
  • 14
  • 2
    Make it `RectangleBST,V> extends BST`. But I am not sure why you declare `K extends Comparable super K>` instead of `K extends Comparable`. – tsolakp Feb 11 '19 at 23:41
  • 1
    @tsolakp https://stackoverflow.com/q/25779184/1553851 – shmosel Feb 11 '19 at 23:41
  • @shmosel. Thanks for the link. – tsolakp Feb 11 '19 at 23:44
  • @tsolakp That did indeed fix it. Could you explain why and what exactly was wrong with the way I was initially trying to implement it? (If it's too much trouble) Thanks! – dan Feb 11 '19 at 23:52
  • @Andreas gave a good explanation. Personally I think Java compiler should be able to infer type of `K` in `extends` definition. – tsolakp Feb 11 '19 at 23:56

1 Answers1

3

The generic type parameters don't have to be named the same, so to better see the difference, let's rename them:

BST<A extends Comparable<? super A>, B>
RectangleBST<C, D> extends BST<C, D>

That works similar to a function call:

bst(int a, int b)
rectangleBst(int c, int d) {
    bst(c, d);
}

However, it only works if c is compatible with a. I mean, if C is compatible with A.

It is not, since C can be any type, even a type that doesn't implement/extend Comparable. Since A requires the type parameter to implement/extend Comparable, C is not compatible.

To make it compatible, you also need to restrict C to types that implement/extend Comparable:

RectangleBST<C extends Comparable<? super C>, D> extends BST<C, D>

Now C is compatible with A.


Ok, now use the names you want:

BST<K extends Comparable<? super K>, V>
RectangleBST<K extends Comparable<? super K>, V> extends BST<K, V>

Just remember, that the K in RectangleBST is not the same K as the K in BST. It is a different K that is mapped to the K in BST, same as C was mapped to A.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • I think I got it! Is there then a difference between ```` RectangleBST, D> extends BST ```` and ```` RectangleBST extends BST, D> ```` Or is the first time that the Generic C is responsible for declaring its type restrictions for any other extended class and/or implemented Interfaces? – dan Feb 12 '19 at 06:30
  • 1
    @dan The second is not valid syntax. Same as you can't write `rectangleBst(c, d) { bst(int c, int d); }`. The type/restriction must be defined where the parameter is *declared*, not where it is used. – Andreas Feb 12 '19 at 17:10