繁体   English   中英

泛型类型多态混淆?

[英]Generic type polymorphism confusion?

我有一个像这样的抽象工厂:

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>

以这种方式定义抽象方法(注意?而不是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>

出现这种情况的原因是,你试图返回EntryDaoImpl<EntryDTOImpl>这是一个亚型EntryDao<EntryDTOImpl>但不是EntryDao<EntryDTO>这是该方法的返回类型。

解:

我相信你想要将getEntryDao方法的返回类型更改为

EntryDAO<? extends EntryDTO> EntryDAO<? extends EntryDTO>

只需将EntryDao<T>的返回类型更改为EntryDao<? extends 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 EntryDTOCarDTO 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> EntryDao<? extends EntryDTO> 只有EntryDao,所有T -accepting方法,如save(T)被删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM