我遇到了javas泛型和重写方法的问题。想象一下,我有一个像树一样深的类层次结构。顶级类定义了方法foo,该方法带有1个类型为Strategy的参数。策略具有通用类型参数。
我的类层次结构中的每个类都需要重写foo以限制可以传递的策略类型,以便策略的通用类型参数与声明的类匹配。下面是一个示例:
abstract class TopLevelClass {
void foo(Strategy<TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
void foo(Strategy<MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass {
void foo(Strategy<LowLevelClass> s) {/*...*/}
}
上面的代码在Java中NOT进行编译。编译时错误为:
名称冲突:MidLevelClass类型的foo(Strategy)方法与TopLevelClass类型的foo(Strategy)具有相同的擦除,但不会覆盖它
我怀疑这很容易解决。我可以只使用原始类型并依靠运行时类型检查,但是我宁愿保持类型安全。在不牺牲类型层次结构或类型安全性的前提下,我该怎么做?请注意,在构造函数中传递策略IS NOT对我来说是一个选择!必须可以在对象的整个生命周期内多次调用foo。
如果您担心擦除,则只需对单独的方法使用单独的方法名称:
abstract class TopLevelClass {
void fooTop(Strategy<TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
void fooMid(Strategy<MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass {
void fooLow(Strategy<LowLevelClass> s) {/*...*/}
}
但是,我怀疑擦除不是您的问题。您大概想重写相同的方法。
您可能要添加通配符:
abstract class TopLevelClass {
void foo(Strategy<? super TopLevelClass> s) {/*...*/}
}
class MidLevelClass extends TopLevelClass {
void foo(Strategy<? super MidLevelClass> s) {/*...*/}
}
class LowLevelClass extends MidLevelClass {
void foo(Strategy<? super LowLevelClass> s) {/*...*/}
}
或在类中添加类型参数以用作方法中的类型参数。
abstract class TopLevelClass<T extends TopLevelClass> {
void foo(Strategy<T> s) {/*...*/}
}
class MidLevelClass<T extends MidLevelClass> extends TopLevelClass<T> {
void foo(Strategy<T> s) {/*...*/}
}
class LowLevelClass<T extends LowLevelClass> extends MidLevelClass<T> {
void foo(Strategy<T> s) {/*...*/}
}