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

これが発生する理由は、メソッドの戻り値の型であるではなく、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

しかし、何EntryDao<? extends EntryDTO>ですか?これは、削除されたTようなすべての受け入れメソッドを備えた単なる EntryDaosave(T)です。

于 2012-09-26T07:28:01.677 に答える