7
implements GenericObserver<DataService, Tools>, GenericObserver<MobileService, Tools>

異なる引数で複数回実装することはできません。

これは私のインターフェースです:

public interface GenericObserver<S, D> {

    void update(S sender, D data);
}

私に何ができる?DataServiceとが必要MobileServiceです。

andTの代わりにジェネリックを使用しようとしましたが、存在しないエラーが発生します。DataServiceMobileServiceT

4

4 に答える 4

14

これは、Java がtype eraseを行うためです。コンパイル後、すべてのジェネリック型が消去され、両方のインターフェイスがバイトコードで同じように見えます。

于 2012-12-09T11:04:29.713 に答える
7

1 つの可能性:

abstract class Service {}

class DataService extends Service {}

class MobileService extends Service {}

class Foo implements GenericObserver<Service, Tools> {
    void update(Service sender, Tools data) {
        if (sender instanceOf DataService) {
            // do something
        } else if (sender instanceOf MobileService) {
            // do something else
        } else {
            // throw some notImplemented exception
        }
    }
}

訪問者パターンは別の可能性です (訪問GenericObserver可能なものです)。

于 2012-12-09T11:02:52.170 に答える
2

実装クラスは、以下のようにルックアップメソッドを提供する機能としてこれらのインターフェイスを提供できます。このパターンの利点は、クラスの API の拡張性と切り離しです。

interface DataObserver extends GenericObserver<DataService, Tools> { }

interface MobileObserver extends GenericObserver<MobileService, Tools> { }

public class Implementor {

    private DataObserver dataObserver;
    private MobileObserver mobileObserver;

    public <T> T lookup(Class<T> klazz) {
        ... return dataObserver;
    }

}
于 2012-12-09T11:12:25.007 に答える
1

なぜこれをやろうとしているのか、2 つのシナリオが考えられます。

この最初のもの - GenericObserver と GenericObserver の両方が、クラス インターフェイスの実装に不可欠です。この場合、オブジェクトは可能な限り特殊化する必要があるため、おそらく設計上の欠陥があります (つまり、1 つのクラスで両方を混合するよりも、それぞれ特殊なタスクに集中する 2 つの異なるクラスを使用する方が適切です)。したがって、GenericObserver を実装するクラスと GenericObserver を実装するクラスの 2 つの別個のクラスを作成する必要があります。GenericObserver を異なる型引数で 2 回実装しようとすると、Java のジェネリックは消去を使用して実装され、GenericObserver と GenericObserver は実行時に本質的に同じ GenericObserver になるため、コンパイラは文句を言います。

2 番目のシナリオ - これらのインターフェースは、実装の詳細の一部です。次に、内部クラス (または静的なネストされたクラス) を使用して目標を達成できます。例えば:

public class OuterClass {

    private String hello = "Hello";
    private String world = "World";

    private class InnerClass1 implements GenericObserver<DataService, Tools> {
        public String interfaceMethod() {
            return hello + " " + world;
        }
        // more implementation
    }

    private class InnerClass2 implements GenericObserver<MobileService, Tools> {
        // implementation
    }

}

内部クラスを使用すると、この少し不自然な例からわかるように、包含クラスのフィールドに簡単にアクセスできます。

于 2012-12-09T11:07:41.263 に答える