2

I am trying to create a hierarchy of classes, starting with an abstract class with a generic type. And then use an extended type of the generic in the 2nd generation of children classes. Since i'm pretty sure that's unclear, here's an example :

The idea would be to have a table of items, so basically :

Simple UML of what I'm trying to do

abstract class AbstractTableOfItems<T> -> The generic type of table

class Foo -> One type of item

class Bar -> Another type on item

class SonOfFoo extends Foo

class TableOfFoo extends AbstractTableOfItems<Foo>

class TableOfBar extends AbstractTableOfItems<Bar>

So far so good, everything is fine (let's not care about the content of classes, it's not the point here).

But then, I want a table of SonOfFoo and I want it to extend TableOfFoo since SonOfFoo inherits from Foo. This does not seem to be possible. Perhaps I'm thinking the wrong way, but I just don't understand why.

class TableOfSonOfFoo extends TableOfFoo

compiles but is wrong, because it would still be a table of Foo, the generic type used being Foo.

class TableOfSonOfFoo extends TableOfFoo<SonOfFoo>

not does compile, since the generic type is on the AbstractTableOfItems.

So ok I say, let's try to redefine TableOfFoo so it can accept inheritance :

class TableOfFoo extends AbstractTableOfItems<? extends Foo>

wrong again, "A supertype may not specify any wildcard" (I'm not sure I fully understand this one).

I cannot touch AbtractTableOfItems, since it wouldn't be as generic as I want. So I'm kinda stuck here. I understand it would work by just having TableOfSonOfFoo inherit directly from AbstractTableOfItems, but then I'd lose all the implementations from TableOfFoo.

I could go around this, but I'm trying to think of a hierarchy, and understanding why this won't work.

3 Answers 3

4

This will compile:

class TableOfFoo<F extends Foo> extends AbstractTableOfItems<F>

That said: I don't like the above design. Having concrete types TableOfFoo and TableOfBar implies that these classes are probably doing more than they should. Perhaps you want to check your design and see if you could simplify things by using aggregation instead of inheritance.

Sign up to request clarification or add additional context in comments.

4 Comments

I know, but I was giving an alternative to this part of his question class TableOfFoo extends AbstractTableOfItems<? extends Foo>. I don't think the entire question is easily answerable.
Thanks, this seem to work. The downside is everytime I use the type "F" and the class TableOfFoo, I have to explicitly cast it to Foo, while it was implicit before. But it actually works this way. "Perhaps you want to check your design and see if you could simplify things by using aggregation instead of inheritance." Perhaps indeed, I'm not so sure about the relevance of this design.
@Zazou that doesn't sound right. you should not need casting when using generics correctly. Perhaps you should ask a follow-up question for this
I double checked, it's more subtle than that ; it's a method that is defined in the abstract class returning a T object, and not being reimplemented in TableOfFoo.
1

You can make your TableOfFoo generic, e.g.

class TableOfItems<T> extends AbstractTableOfItems<T>

and pull up all of the functionality that you want to share into that. Then create subclasses of this:

class TableOfFoo extends TableOfItems<Foo>
class TableOfSonOfFoo extends TableOfItems<SonOfFoo>

Bear in mind that AbstractTableOfItems<Foo> is not a supertype of AbstractTableOfItems<SonOfFoo>, so TableOfFoo and TableOfSonOfFoo are actually siblings in the hierarchy.

4 Comments

Thanks for the answer, but by doing this, TableOfItems would be a table of generic items "T" and not a table of Foo, which means I can't use Foo as my generic type in the methods of this class. Which was precisely the point of this hierarchy.
@Zazou so add a bound to the type variable: T extends Foo.
But then it would be a TableOfFoo, and TableOfItems would not be needed, and that would be the answer from Sean Patrick Floyd, right above ;)
Well, it's not the same. But if his answer works for you, great.
0

Would have rather written this into comments, but don't have enough reputation yet. Have you tried:

class TableOfSonOfFoo extends AbstractTableOfItems<SonOfFoo>

This seems legit to me and would have been my first guess.

1 Comment

1) Please don't write questions as an answer. If you don't have enough reputation for comments then answer questions until you have. 2) OP explicitely explained that he doesn't want to directly extend AbstractTableOfItems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.