接口xxx不能使用不同的参数多次实现:

时间:2012-12-09 10:50:41

标签: java

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

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

这是我的界面:

public interface GenericObserver<S, D> {

    void update(S sender, D data);
}

我该怎么办?我需要DataServiceMobileService

我尝试使用通用T代替DataServiceMobileService,但我收到T不存在的错误。

4 个答案:

答案 0 :(得分:14)

这是因为Java在做type erasure。在编译之后,所有泛型类型都被擦除,两个接口在字节码中看起来都是相同的。

答案 1 :(得分: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
        }
    }
}

Visitor pattern是另一种可能性(GenericObserver是可访问的)。

答案 2 :(得分: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;
    }

}

答案 3 :(得分: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
    }

}

如果您使用内部类,那么您可以轻松访问包含类的字段,您可以从这个有点人为的例子中看到。