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

不能使用不同的参数多次实现。

这是我的界面:

public interface GenericObserver<S, D> {

    void update(S sender, D data);
}

我能做些什么?我需要DataServiceMobileService

我尝试使用通用T而不是,DataServiceMobileService我得到一个T不存在的错误。

4

4 回答 4

14

这是因为 Java 进行了类型擦除。编译后,所有泛型类型都被删除,两个接口在字节码中看起来相同。

于 2012-12-09T11:04:29.713 回答
7

一种可能:

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

我看到两种可能的情况,您为什么要这样做:

第一个 - GenericObserver 和 GenericObserver 对于实现类接口都是必不可少的。在这种情况下,您可能存在设计缺陷,因为对象应该尽可能专门化(即最好有两个不同的类,每个类都专注于专门的任务,而不是一个类混合它们)。因此,您可能应该创建两个单独的类,一个实现 GenericObserver,另一个实现 GenericObserver。当您尝试使用不同类型参数两次实现 GenericObserver 时,编译器会抱怨,因为 Java 中的泛型是使用擦除实现的,因此 GenericObserver 和 GenericObserver 在运行时本质上是相同的 GenericObserver。

第二种情况 - 这些接口是您的实现细节的一部分。然后您可以使用内部类(或静态嵌套类)来实现您的目标。例如:

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 回答