TL; DR有没有办法强制方法接收子类而不是父类?
说我有一个像:
这样的界面interface MyInterface<T extends A>{
process(A a)
}
和班级
abstract class A<T extends A>{
MyInteface<T>[] processors
}
两个子类B和C如:
class B extends A<B>{}
class C extends A<C>{}
我想这样做,以便MyInterface的实现可以做类似的事情:
class MyImplementation implements MyInterface<B>, MyInterface<C>{
process(B)
process(C)
}
我认为这是不可能的,因为如果将超类A传递给MyImplementation,编译器将无法告诉您该怎么做。
是否可以强制MyImplementation只接收子类?如果没有,你会如何处理这个问题?
答案 0 :(得分:0)
由于Java中的type erasure,这是不可能的:在运行时,与泛型相关的类型信息不再可用。例如:
List<Number> numbers = new ArrayList<>();
List<String> strings = new ArrayList<>();
// At runtime, these types actually look like this:
List numbers = new ArrayList();
List strings = new ArrayList();
因此,单个类不能使用不同的泛型类型参数多次实现相同的通用接口。在编译期间,class MyImplementation implements MyInterface<B>, MyInterface<C> { /* ... */ }
将失败。这样做会导致以下错误:
接口
MyInterface
不能多次实现 不同的论点:MyInterface<C>
和MyInterface<B>
删除类型后,此类等于class MyImplementation implements MyInterface, MyInterface { /* ... */ }
,这在Java中显然是不允许的。
<强>替代强>
好像您正在寻找要更改的调用的功能,具体取决于使用哪个类来处理元素(MyInterface<B>
,MyInterface<C>
等)以及哪个元素是已处理(A
,B
,C
等)。这称为double-dispatch,与Visitor Pattern密切相关。在您的问题的上下文中,您可以执行以下操作:
public interface Element {
public void accept(Processor processor);
}
public class A implements Element {
@Override
public void accept(Processor processor) {
processor.process(this);
}
}
public class B implements Element {
@Override
public void accept(Processor processor) {
processor.process(this);
}
}
public interface Processor {
public void process(A a);
public void process(B b);
}
public class RedProcessor implements Processor {
@Override
public void process(A a) {
System.out.println("Red processor got an A");
}
@Override
public void process(B b) {
System.out.println("Blue processor got an A");
}
}
public class BlueProcessor implements Processor {
@Override
public void process(A a) {
System.out.println("Blue processor got an A");
}
@Override
public void process(B b) {
System.out.println("Blue processor got an A");
}
}
可以使用以下方法测试此代码:
Processor processor = new RedProcessor();
A a = new A();
processor.process(a);
改变Processor
实施(例如RedProcessor
或BlueProcessor
)和Element
实施(例如A
或B
)会导致不同的输出。由于结果取决于Processor
和Element
,因此此技术称为 double -dispatch。