2013-07-12 2 views
0

У меня есть следующая структура классов.Дженерики переопределяют путаницу

public abstract class X { } 
public class Y extends X { } 

И я хочу сделать следующее:

public abstract class Action { 
    public abstract <T extends X> void execute(T t); 
} 

public class SomeAction extends Action { 
    public void execute(Y y) { } 
} 

Компилятор дает мне следующую ошибку:

The Type SomeAction must implement the inherited abstract method Action.execute(T)

Я хочу, чтобы переопределить execute(), но я хочу, чтобы параметр быть подклассом X.

Что я здесь делаю неправильно?

ответ

1

Это звучит, как вы хотите T extends X быть свойством класса расширения Action, а не метод призывание. Вы должны написать

public abstract class Action<T extends X> { 
    public abstract void execute(T t); 
} 

, а затем

public class SomeAction extends Action<Y> { 
    ... 
} 
+0

Спасибо, что сделали :) – AM01

1
public <T extends X> void execute(T t); 

- абстрактный метод, поскольку он не имеет никакого тела. он должен быть отмечен как абстрактный.

Итак, в вашем классе-потомке вы должны переопределить это или отметить как метод, так и подкласс как абстрактный.

+0

Спасибо, я отредактировал вопрос. Я пропустил это по ошибке. – AM01

2

Попробуйте сделать класс Action общим, а не одним из его методов.

public abstract class Action<T extends X> 
{ 
    public abstract void execute(T t); 
} 

Затем можно назначить общий параметр типа T быть Y в SomeAction:

public class SomeAction extends Action<Y> 
{ 
    public void execute(Y y) {} 
} 
+0

Спасибо, что сделали :) – AM01

1

Вы нарушаете принцип Лиск: execute метода базового Action в состоянии выполнить любой вид X. Но в подклассе, ограничить его выполнение только Y-экземпляров. Это сокращает контракт, а не расширяет его.

+0

Базовый класс X является абстрактным. – AM01

+1

И что? Он по-прежнему определяет контракт через свои общедоступные методы, и все реализации должны подчиняться контракту. –

+1

Общий метод в классе Action относится к вызову его с типом и возврату того же типа. Это не относится к переопределению метода. Переопределение, как объяснил @JBNizet, должно соответствовать сигнатуре метода в родительском ... включая его общие аспекты. –

Смежные вопросы