2

オーバーライドする必要がある抽象クラスにジェネリックを適切に実装する際に問題があります。

public abstract class AbstractSerachView {
    DataStore<AbstractCriteria, AbstractResults, AbstractService> resultsStore;
    public abstract DataStore<AbstractCriteria, AbstractResults, AbstractService> getResultsStore();
}

子クラスは次のとおりです。

public class TravelSearchView extends AbstractSearchView {
    DataStore<TravelCriteria, TravelResults, TravelService> resultsStore;
    public DataStore<TravelCriteria, TravelResults, TravelService> getResultsStore() {
        return resultsStore;
    }
}

この種の抽象化はまったく機能しませんが、何らかの方法でこの作業を行うことができれば非常にありがたいです. ここで正しいアプローチは何ですか?ジェネリック型の経験はほとんどありません。

問題は、Eclipse が子クラスのエラーを示していることです。戻り値の型は AbstractSearchView.getResultsStore() と互換性がありません。

さらに、子クラスの get メソッドを 3 つの抽象型のままにし、変数を 3 つの travel 型でオーバーライドすると、Eclipse が示すリターン行を除いてすべて問題ありません: Type mismatch: Cannot convert from DataStore to DataStore

4

3 に答える 3

4

これを行う最良の方法は、基本クラス(またはインターフェイス)をジェネリックにすることです。

public abstract class AbstractSerachView<
    TCriteria extends AbstractCriteria>,
    TResults extends AbstractResults,
    TService extends AbstractService>
{
    DataStore<TCriteria, TResults, TService> resultsStore;
    public DataStore<TCriteria, TResults, TService> getResultsStore()
    {
        return resultsStore;
    }
}

次に、実装では具体的なタイプを提供するだけです

public class TravelSearchView
    extends AbstractSearchView<TravelCriteria, TravelResults, TravelService>
{
}

また、ご覧のとおり、実装クラスはgetResultsStoreメソッドをオーバーライドする必要はありません。

于 2012-05-17T15:55:03.987 に答える
4

別の戻り値の型でオーバーライドする場合はAbstractSearchView、クラスで各パラメーターのジェネリック パラメーターを指定する必要があります。DataStoregetResultsStore()

public abstract class AbstractSearchView<C extends AbstractCriteria, R extends AbstractResults, S extends AbstractService> {
    DataStore<AbstractCriteria, AbstractResults, AbstractService> resultsStore;
    public abstract DataStore<AbstractCriteria, AbstractResults, AbstractService> getResultsStore();
}

public class TravelSearchView extends AbstractSearchView<TravelCriteria, TravelResults, TravelService> {
    DataStore<TravelCriteria, TravelResults, TravelService> resultsStore;
    public DataStore<TravelCriteria, TravelResults, TravelService> getResultsStore() {
        return resultsStore;
    }
}

のパラメータのスーパータイプ境界 ( X extends SomeClass) は、 のサブクラスがそれらの各パラメータのサブタイプのみを使用できることをAbstractSearchView保証します。AbstractSearchView

于 2012-05-17T15:53:08.993 に答える
3

代替案は次のとおりです。

a) スーパークラスの型シグネチャを次のように変更します

    public DataStore<? extends AbstractCriteria, ? extends AbstractResults, ? extends AbstractService> getResultsStore();

b) 型パラメータをクラス全体に追加します。

 abstract class AbstractSearchView<
     C extends AbstractCriteria,
     R extends AbstractResults,
     S extends AbstractService>
  public abstract DataStore<C, R, S> getResultsStore();
 } 
 class TravelSearchView extends AbstractSearchView<
     TravelCriteria, TravelResults, TravelService> {
   ...
 }

問題は、それらのジェネリック型引数がそれぞれサブタイプであっても、 のサブタイプでDataStore<TravelCriteria, TravelResults, TravelService>ないことです。DataStore<AbstractCriteria, AbstractResults, AbstractService>

于 2012-05-17T15:42:49.237 に答える