我有一个像这样的抽象工厂:
public abstract class DAOFactory {
public abstract EntryDAO<EntryDTO> getEntryDAO();
...
}
使用我的DAO和DTO界面:
public interface EntryDTO extends GenericDTO {
}
public interface EntryDAO<T extends EntryDTO> extends GenericDAO<T, Serializable> {
}
我的实施如下:
public class EntryDTOImpl implements EntryDTO {
}
public class EntryDAOImpl<T extends EntryDTO> extends GenericDaoImpl<EntryDTOImpl, ObjectId>
implements EntryDAO<T> {
}
现在,如果我创建一个工厂并覆盖getEntryDAO
方法,如下所示:
public class MyDAOFactory extends DAOFactory {
@Override
public EntryDAO<EntryDTO> getEntryDAO() {
try {
return new EntryDAOImpl<EntryDTOImpl>();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
我收到编译时错误:
类型不匹配:无法从EntryDAOImpl转换为EntryDAO
修改
我已经更新了我的抽象工厂:
public abstract <T extends EntryDTO> EntryDAO<T> getEntryDAO();
并改变了我的工厂实施:
@Override
public <T extends EntryDTO> EntryDAO<T> getEntryDAO() {
try {
return new EntryDAOImpl<EntryDTOImpl>();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
现在我收到了编译时错误:
Type mismatch: cannot convert from EntryDAOImpl<EntryDTOImpl> to EntryDao<T>
答案 0 :(得分:2)
以这种方式定义抽象方法(注意?
而不是T
):
public abstract EntryDAO<? extends EntryDTO> getEntryDAO(); //should work for you
我按照我理解的方式重新创建了方案:将subclass1<subclass2>
作为interface1<interface2>
例如,这很有效:
public static List<? extends CharSequence> dostuff1() {
return new ArrayList<String>();
}
但这不起作用:
public <B extends CharSequence> List<B> dostuff2() {
return new ArrayList<String>();
}
这会产生相同的编译时错误:Type mismatch: cannot convert from ArrayList<String> to List<B>
答案 1 :(得分:1)
发生这种情况的原因是您尝试返回的EntryDaoImpl<EntryDTOImpl>
是EntryDao<EntryDTOImpl>
的子类型,而不是EntryDao<EntryDTO>
的子类型,这是getEntryDao
的返回类型方法
<强>解决方案:强>
我相信您想要将EntryDAO<? extends EntryDTO>
方法的返回类型更改为
{{1}}。
答案 2 :(得分:1)
只需将返回类型从EntryDao<T>
更改为EntryDao<? extends T>
即可。这样就可以了:
@Override
public <T extends EntryDto> EntryDao<? extends T> getEntryDao() {
try {
return new EntryDAOImpl<EntryDTOImpl>();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dao;
}
现在作为理由,假设EntryDao<T>
有返回T
的方法
T load(Serializable id);
和接受T
的方法
void save(T t);
现在假设PersonDTO extends EntryDTO
和CarDTO extends EntryDTO
。
如果EntryDao<EntryDTO>
可以EntryDao<EntryDTOImpl>
分配,EntryDao<PersonDTO>
也可以分配EntryDao<CarDTO>
和EntryDao<EntryDTO> x = new EntryDao<PersonDTO>(); // currently this is a compile time error
。
然后你可以这样做:
x.save(new CarDTO()); // a run time error, because x can only save Persons, not Cars
如果这是合法的,你可以这样做:
EntryDao<? extends EntryDTO>
但是T
是什么?只有EntryDao包含所有save(T)
- 接受{{1}}等方法。