[英]Generic type polymorphism confusion?
I have an abstract factory like so: 我有一个像这样的抽象工厂:
public abstract class DAOFactory {
public abstract EntryDAO<EntryDTO> getEntryDAO();
...
}
With my DAO and DTO interfaces like so: 使用我的DAO和DTO接口如下:
public interface EntryDTO extends GenericDTO {
}
public interface EntryDAO<T extends EntryDTO> extends GenericDAO<T, Serializable> {
}
And my implementation like so: 我的实现如下:
public class EntryDTOImpl implements EntryDTO {
}
public class EntryDAOImpl<T extends EntryDTO> extends GenericDaoImpl<EntryDTOImpl, ObjectId>
implements EntryDAO<T> {
}
Now, if I create a factory and override the getEntryDAO
method like so: 现在,如果我创建一个工厂并覆盖
getEntryDAO
方法,如下所示:
public class MyDAOFactory extends DAOFactory {
@Override
public EntryDAO<EntryDTO> getEntryDAO() {
try {
return new EntryDAOImpl<EntryDTOImpl>();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
I get a compile time error: 我得到一个编译时错误:
Type mismatch: cannot convert from EntryDAOImpl to EntryDAO
类型不匹配:无法从EntryDAOImpl转换为EntryDAO
EDIT 编辑
I've updated my abstract factory like so: 我像这样更新了我的抽象工厂:
public abstract <T extends EntryDTO> EntryDAO<T> getEntryDAO();
And made the change in my factory implementation: 并改变了我的工厂实施:
@Override
public <T extends EntryDTO> EntryDAO<T> getEntryDAO() {
try {
return new EntryDAOImpl<EntryDTOImpl>();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Now I'm getting the compile time error: 现在我收到编译时错误:
Type mismatch: cannot convert from EntryDAOImpl<EntryDTOImpl> to EntryDao<T>
Define the abstract method this way (notice ?
instead of T
): 以这种方式定义抽象方法(注意
?
而不是T
):
public abstract EntryDAO<? extends EntryDTO> getEntryDAO(); //should work for you
I recreated the scenario the way I understood it: returning subclass1<subclass2>
as interface1<interface2>
我按照我理解的方式重新创建了场景: 将
subclass1<subclass2>
作为interface1<interface2>
For example, this works well: 例如,这很好用:
public static List<? extends CharSequence> dostuff1() {
return new ArrayList<String>();
}
But this doesn't work: 但这不起作用:
public <B extends CharSequence> List<B> dostuff2() {
return new ArrayList<String>();
}
This gives the same compile-time error that you got: Type mismatch: cannot convert from ArrayList<String> to List<B>
这给出了相同的编译时错误:
Type mismatch: cannot convert from ArrayList<String> to List<B>
The reason this is happening is that you're trying to return an EntryDaoImpl<EntryDTOImpl>
, which is a subtype of EntryDao<EntryDTOImpl>
, but not of EntryDao<EntryDTO>
, which is the return type of the method. 出现这种情况的原因是,你试图返回
EntryDaoImpl<EntryDTOImpl>
这是一个亚型EntryDao<EntryDTOImpl>
但不是EntryDao<EntryDTO>
这是该方法的返回类型。
Solution: 解:
I believe you want to change the return type of the getEntryDao
method to 我相信你想要将
getEntryDao
方法的返回类型更改为
EntryDAO<? extends EntryDTO>
EntryDAO<? extends EntryDTO>
. EntryDAO<? extends EntryDTO>
。
Just change the return type from EntryDao<T>
to EntryDao<? extends T>
只需将
EntryDao<T>
的返回类型更改为EntryDao<? extends T>
EntryDao<? extends T>
. EntryDao<? extends T>
。 That will do the trick: 这样就可以了:
@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;
}
Now as a justification, suppose EntryDao<T>
has methods that return T
like 现在作为理由,假设
EntryDao<T>
具有返回T
方法
T load(Serializable id);
and methods that accept T
like 以及接受
T
类的方法
void save(T t);
Now assume PersonDTO extends EntryDTO
, and CarDTO extends EntryDTO
. 现在假设
PersonDTO extends EntryDTO
, CarDTO extends EntryDTO
。
If EntryDao<EntryDTO>
were assignable from EntryDao<EntryDTOImpl>
, it would also be assignable form EntryDao<PersonDTO>
and EntryDao<CarDTO>
. 如果
EntryDao<EntryDTO>
可从EntryDao<EntryDTOImpl>
分配,则它也可以从EntryDao<PersonDTO>
和EntryDao<CarDTO>
分配。
Then you could do: 然后你可以这样做:
EntryDao<EntryDTO> x = new EntryDao<PersonDTO>(); // currently this is a compile time error
If that were legal, you could do: 如果这是合法的,你可以这样做:
x.save(new CarDTO()); // a run time error, because x can only save Persons, not Cars
But what is EntryDao<? extends EntryDTO>
但什么是
EntryDao<? extends EntryDTO>
EntryDao<? extends EntryDTO>
? EntryDao<? extends EntryDTO>
? It is just EntryDao with all T
-accepting methods like save(T)
removed. 只有EntryDao,所有
T
-accepting方法,如save(T)
被删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.