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

В любом случае, я новичок в дженериках и поэтому не совсем понимаю синтаксис. Но вот моя ситуация:

У меня есть интерфейс (назовем его IService ) и реализация ( ServiceImpl ). Класс реализации имеет абстрактный метод, который должен быть переопределен расширяющимся классом ( ServiceExt ).

У меня есть абстрактный компонент (назовем его AbstractBean ), который имеет несколько полей и предназначен для расширения другим компонентом ( BeanExt ), чтобы добавить еще несколько полей.

Хорошо, теперь, когда ситуация изложена, вот мой сокращенный код:

Интерфейс:

public interface IService <B extends AbstractBean> {
    B method(B bean, Object data) throws Exception;
}

Реализация:

public abstract class ServiceImpl <B extends AbstractBean> implements IService<B> {
    public abstract B method(B bean, Object data);
}

Абстрактный компонент :

public abstract class AbstractBean{

    private String fname;

    private String lname;

    [getters and setters]
}

Расширенный компонент:

public class BeanExt extends AbstractBean{

    private String phoneNum;

    [getter and setter]
}

Расширение класса: он же класс, вызывающий у меня проблемы

public class ServiceExt <B extends AbstractBean> extends ServiceImpl <B> {

    @Override
    public <B> BeanExt method(Bbean, Object data) {
        if(beaninstanceof AbstractBean){
            BeanExt beanExt = (BeanExt) session;
            beanExt.setFname("John");
            beanExt.setLname("Doe");
            beanExt.setPhoneNum("123456789");
            return beanExt;
        }else{
            return null;
        }
    }
}

Хорошо, теперь eclipse вызывает у меня всевозможные проблемы, не связанные с описанием, и я не знаю, что делать. Я много экспериментировал с методами расширения класса, но не добился успеха. Выше показано, как он выглядит после моей последней переделки.

В настоящее время моя IDE в классе ServiceExt представляет следующие проблемы:

  • Метод метода (B, Object) типа ServiceImpl должен переопределять или реализовывать метод супертипа.
  • Тип ServiceExt должен реализовывать унаследованный абстрактный метод [некоторый другой неабстрактный метод в интерфейсе]

Изменить. Для дальнейшего уточнения я в конечном итоге пытаюсь сделать следующее:

  • Создайте bean-компонент, расширяющий AbstractBean, и добавьте еще одно поле
  • Определите абстрактный метод внутри класса ServiceExt
  • Внутри метода установите некоторые значения в расширенном bean-компоненте
  • Вернуть расширенный bean-компонент с его новыми значениями

Обновление . Я принял все ваши комментарии и изменения отражены ниже. Проблема, которую сейчас представляет моя IDE в классе ServiceExt :

  • Тип ServiceExt должен реализовывать унаследованный абстрактный метод [некоторый другой неабстрактный метод в интерфейсе]

Интерфейс:

public interface IService <B extends AbstractBean> {
    B method(B bean, Object data) throws Exception;
    B otherMethod(HttpServletRequest request) throws Exception;
}

Реализация:

public abstract class ServiceImpl <B extends AbstractBean> implements IService<B> {
    public abstract B method(B bean, Object data);

    @Override
    public final B otherMethod(HttpServletRequest request) {
        return [something]; 
    }
}

Абстрактный компонент :

public abstract class AbstractBean{

    private String fname;

    private String lname;

    [getters and setters]
}

Расширенный компонент:

public class BeanExt extends AbstractBean{

    private String phoneNum;

    [getter and setter]
}

Расширение класса: он же класс, вызывающий у меня проблемы

public class ServiceExt extends ServiceImpl <BeanExt> {

    @Override
    public BeanExt method(BeanExt bean, Object data) {
        BeanExt beanExt = (BeanExt) session;
        beanExt.setFname("John");
        beanExt.setLname("Doe");
        beanExt.setPhoneNum("123456789");
        return beanExt;
    }
}
1
Mike 26 Мар 2014 в 18:57
Ваш ServiceImpl не компилируется. Является ли implements IService<S> опечаткой? Должно быть implements IService<B>. Пожалуйста, проверьте.
 – 
Bohemian
26 Мар 2014 в 19:08
Извините за это, это было исправлено
 – 
Mike
26 Мар 2014 в 19:10
Я в замешательстве. Казалось, мы все решили вашу первую проблему (то есть ошибки компилятора). Теперь ваша проблема изменилась? Обратите внимание, что это затрудняет вам помощь.
 – 
Duncan Jones
26 Мар 2014 в 19:12
1
Какие? Вы изменили свой вопрос на основе ответов? Все ответы теперь недействительны.
 – 
Rohit Jain
26 Мар 2014 в 19:20
1
Ваш модифицированный код должен работать нормально.
 – 
Rohit Jain
26 Мар 2014 в 19:26

3 ответа

Лучший ответ

На самом деле вы не переопределяете метод в суперклассе. Вот переопределенный метод:

@Override
public BeanExt method(BeanExt bean, Object data) {
        BeanExt beanExt = (BeanExt) session;
        beanExt.setFname("John");
        beanExt.setLname("Doe");
        beanExt.setPhoneNum("123456789");
        return beanExt;
}

Поскольку вы расширяете ServiceImpl<BeanExt>, параметр типа B заменяется на тип BeanExt, как и возвращаемый тип и параметр метода.

Также обратите внимание, что я удалил проверку instanceof, поскольку она действительно не нужна. bean всегда будет экземпляром AbstractBean, потому что это обеспечивается привязкой, которую вы дали объявлению параметра типа класса ServiceImpl.

2
Rohit Jain 26 Мар 2014 в 19:08

Я не совсем понял, что вы пытаетесь сделать, но приемлемо ли это / работает?

public class ServiceExt <B extends BeanExt> extends ServiceImpl <B> {

    @Override
    public B method(B bean, Object data) {
        bean.setFname("John");
        bean.setLname("Doe");
        bean.setPhoneNum("123456789");
        return bean;
    }
}
0
Flavio 26 Мар 2014 в 19:06

Я просто исправил все ошибки:

interface IService <B extends AbstractBean> {
    B method(B bean, Object data) throws Exception;
}

abstract class ServiceImpl <B extends AbstractBean> implements IService<B> {
    public abstract B method(B bean, Object data);
}

abstract class AbstractBean{

    String fname;
    String lname;
}

class BeanExt extends AbstractBean {

    String phoneNum;
}

class ServiceExt <B extends AbstractBean> extends ServiceImpl <B> {

    @Override public B method(B bean, Object data) {
        if (bean instanceof BeanExt) {
            BeanExt beanExt = (BeanExt) bean;
            beanExt.fname = "John";
            beanExt.lname = "Doe";
            beanExt.phoneNum = "123456789";
            return bean;
        }else{
            return null;
        }
    }
}
0
Harmlezz 26 Мар 2014 в 19:08