views:

241

answers:

3
public abstract class AbstractTool<AT extends AbstractThing> {
    protected ArrayList<AT> ledger;
    public AbstractTool() {
     ledger = new ArrayList<AT>();
    }

    public AT getToolAt(int i) {
     return ledger.get(i);
    }

    // More code Which operates on Ledger ...

}

public class Tool<AT extends AbstractThing> extends AbstractTool {
    public Tool() {
     super();
    }
}

How do I correctly call super to pass the AT generic of Tool to the AbstractTool constructor?

It seems no matter what I pick AT to be when I declare Tool (Say, Tool<Thing>), that I always get back an AbstractThing instead of Thing. This seems to defeat the purpose of generics...

Help?

+5  A: 
public class Tool<AT extends AbstractThing> extends AbstractTool<AT> {

In other words, if you extend or implement something with generics, remember to define the generics arguments for them.

iny
In fact in this case, because the type constraints on AbstractTool's generic parameter will be inherited, you could just write `public class Tool<AT> extends AbstractTool<AT>`. This would be functionally equivalent since AbstractTool's definition would stop you using a generic parameter that wasn't an `AbstractThing`.
Andrzej Doyle
+2  A: 

Shouldn't it rather be Tool<AT extends...> extends AbstractTool<AT>?

ShiDoiSi
A: 

I think what you probably want is:

   public abstract class AbstractTool<AT extends AbstractThing> {
        protected List<AT> ledger = new ArrayList<AT>();

        public AT getToolAt(int i) {
            return ledger.get(i);
        }

        // More code Which operates on Ledger ...

    }

    public class Tool extends AbstractTool<Thing> {
        // Tool stuff ...
    }

Since Tool is a concrete class, it doesn't need to be parametrized itself. There is no need for the constructors if you initialize the List (oh and remember to program to the interface) at declaration, and because it is protected the subclasses can access it directly.

Robert