Generics: наследование от абстрактного класса, который реализует интерфейс - PullRequest
17 голосов
/ 27 марта 2012

У меня есть следующий интерфейс:

public interface SingleRecordInterface<T> {
    public void insert(T object);
}

У меня есть абстрактный класс ниже (в нем не упоминается метод insert):

public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {
}

У меня есть конкретный класс:

public class SpecificEntry extends AbstractEntry {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}

Наконец, SpecificEntryBean определяется как:

public class SpecificEntryBean extends AbstractEntryBean {
}

У меня следующая ошибка:

Тип SpecificEntry должен реализовывать унаследованный абстрактный метод SingleRecordInterface.insert (AbstractEntryBean)

Я не понимаю причину этой ошибки, учитывая, что SpecificEntryBean расширяет AbstractEntryBean. Как я могу исправить эту ошибку?

Ответы [ 4 ]

35 голосов
/ 27 марта 2012

Вы должны сделать свой абстрактный класс также общим:

public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}

Тогда для вашего конкретного класса:

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
}
3 голосов
/ 27 марта 2012

Изменить на следующее:

public abstract class AbstractEntry<EB extends AbstractEntryBean> implements SingleRecordInterface<EB> {
}

и

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}
2 голосов
/ 27 марта 2012

Проблема в вашем объявлении

public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {}

Это место, где вы определяете, что является аргументом типа (AbstracEntryBean) для параметра типа T.

Следовательно, T это AbstracEntryBean, и когда вы намереваетесь переопределить этот метод для его окончательной реализации, вам необходимо предоставить точную сигнатуру метода для метода.В этом случае:

@Override
public void insert(AbstractEntryBean object) {
    // TODO Auto-generated method stub
}

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

Вы можете либо предоставить параметр типа для своего класса, как предлагали другие, либопредоставить метод моста (перегрузки) следующим образом:

//overloading
public void insert(SpecificBean object){
  insert((AbstractEntryBean) object);
}
1 голос
/ 27 марта 2012
public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...