Я много исследовал эту проблему, но мне не удалось найти решение, близкое к моей ситуации. Прошу прощения, если я лишний.
В любом случае, я новичок в дженериках и поэтому не совсем понимаю синтаксис. Но вот моя ситуация:
У меня есть интерфейс (назовем его 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;
}
}
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
.
Я не совсем понял, что вы пытаетесь сделать, но приемлемо ли это / работает?
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;
}
}
Я просто исправил все ошибки:
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;
}
}
}
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
ServiceImpl
не компилируется. Является лиimplements IService<S>
опечаткой? Должно бытьimplements IService<B>
. Пожалуйста, проверьте.