Расширение общего абстрактного класса и правильное использование Super - PullRequest
11 голосов
/ 13 сентября 2009
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();
    }
}

Как правильно вызвать super, чтобы передать AT универсальный Tool в конструктор AbstractTool?

Кажется, что бы я ни выбрал AT, когда я заявляю Tool (скажем, Tool<Thing>), что я всегда получаю AbstractThing вместо Thing. Это, кажется, побеждает цель дженериков ...

Помощь

Ответы [ 3 ]

19 голосов
/ 13 сентября 2009
public class Tool<AT extends AbstractThing> extends AbstractTool<AT> {

Другими словами, если вы расширяете или реализуете что-то с помощью обобщений, не забудьте определить для них аргументы обобщений.

3 голосов
/ 13 сентября 2009

Разве это не должно быть Tool<AT extends...> extends AbstractTool<AT>

0 голосов
/ 13 сентября 2009

Я думаю, что вы, вероятно, хотите:

   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 ...
    }

Поскольку Tool является конкретным классом, его не нужно параметризировать. Конструкторам нет необходимости, если вы инициализируете List (о, не забывайте программировать для интерфейса) при объявлении, и поскольку он защищен, подклассы могут обращаться к нему напрямую.

...