1

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

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>

4

3 回答 3

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>

于 2012-09-26T03:25:09.217 回答
1

发生这种情况的原因是您试图返回 an EntryDaoImpl<EntryDTOImpl>,它是 的子类型 EntryDao<EntryDTOImpl>,但不是EntryDao<EntryDTO>,它是方法的返回类型。

解决方案:

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

EntryDAO<? extends EntryDTO>.

于 2012-09-26T03:27:51.643 回答
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 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

But what is EntryDao<? extends EntryDTO>? It is just EntryDao with all T-accepting methods like save(T) removed.

于 2012-09-26T07:28:01.677 回答