implements GenericObserver<DataService, Tools>, GenericObserver<MobileService, Tools>
不能使用不同的参数多次实现。
这是我的界面:
public interface GenericObserver<S, D> {
void update(S sender, D data);
}
我该怎么办?我需要DataService
和MobileService
。
我尝试使用通用T
代替DataService
和MobileService
,但我收到T
不存在的错误。
答案 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
}
}
如果您使用内部类,那么您可以轻松访问包含类的字段,您可以从这个有点人为的例子中看到。