Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - non-generic class extends generic class

I would like to know how (if possible) can I create a class, that is a specific type of a generic class.

To be specific, I have an abstract class Stack<Type> with all necessary methods implemented and I would like to have a class StackInteger while an instance of StackInteger is also an instance of Stack<Integer>.

I see I can do something like this:

class StackInteger {
    Stack<Integer> s;

    public StackInteger(int size) {
        s = new Stack<Integer>(size);
    }

}

and then implement all Stack methods to contain s.method(); but I wonder if I can do it easily while extending from Stack.

like image 349
dannymo Avatar asked Dec 25 '22 21:12

dannymo


2 Answers

I would recommend against extending generic classes just to overcome generics verbosity. This is an antipattern, known as the pseudo-typedef antipattern.

From the article:

if a method parameter is of type StringList, you cannot pass an ordinary List to it. This means that you cannot use pseudotypes at all as method arguments without requiring that every use of that method use the pseudotype, which in practicality means that you cannot use pseudotypes at all in library APIs.

...

A further problem with the pseudo-typedef antipattern is that it tends to ignore the benefit of using interfaces to define the types of variables and method arguments. While it is possible to define StringList as an interface that extends List and a concrete type StringArrayList that extends ArrayList and implements StringList, most users of the pseudo-typedef antipattern generally do not go to this length, as the purpose of this technique is primarily to simplify and shorten type names. As a result, APIs will be less useful and more brittle because they use concrete types like ArrayList rather than abstract types like List.

So, why not sticking to Stack<Integer>? I don't think it's so bad.

like image 20
fps Avatar answered Dec 28 '22 06:12

fps


Yes, in this case, inheritance is a better solution than composition as you have it, because a StackInteger is a Stack.

Just supply Integer as a type argument in the extends clause.

class StackInteger extends Stack<Integer>

However, if you don't supply any additional functionality beyond what Stack already has, then this class is useless and you might as well just use Stack<Integer>.

like image 139
rgettman Avatar answered Dec 28 '22 07:12

rgettman