【发布时间】:2020-02-02 12:53:11
【问题描述】:
我遇到了 javas 泛型和覆盖方法的问题。想象一下,我有一个很深的树状类层次结构。顶级类定义了一个方法 foo,它接受 1 个 Strategy 类型的参数。策略有一个泛型类型参数。
我的类层次结构中的每个类都需要重写 foo 以限制它可以传递的策略类型,以便策略的泛型类型参数与声明类匹配。下面是一个例子:
abstract static class TopLevelClass {
static final Strategy<TopLevelClass> s1 = tlc -> System.out.println(tlc.getTopLevelAtt());
String getTopLevelAtt() {
return "TopLevelAtt";
}
void foo(Strategy<TopLevelClass> s) {s.bar(this);}
}
static class MidLevelClass extends TopLevelClass {
static final Strategy<MidLevelClass> s2 = mlc -> System.out.println(mlc.getMidLevelAtt());
String getMidLevelAtt() {
return "MidLevelAtt";
}
void foo(Strategy<MidLevelClass> s) {s.bar(this);}
}
static class LowLevelClass extends MidLevelClass {
static final Strategy<LowLevelClass> s3 = llc -> System.out.println(llc.getTopLevelAtt());
String getLowLevelAtt() {
return "LowLevelAtt";
}
void foo(Strategy<LowLevelClass> s) {s.bar(this);}
}
static interface Strategy<X> {
void bar(X x);
}
在此示例中,我希望能够在具有分别在 TopLevelClass、MidLevelClass 和 LowLevelClass 中定义的任何静态引用 s1、s2 和 s3 的类 LowLevelClass 的实例上调用 foo。理想情况下,我不必根据参数调用不同的方法 foo1、foo2 或 foo3。
上面的代码不在java中编译。编译时错误是:
名称冲突:MidLevelClass 类型的方法 foo(Strategy) 与 TopLevelClass 类型的 foo(Strategy) 具有相同的擦除,但不会覆盖它
我怀疑这很容易解决。我可以只使用原始类型并依赖运行时类型检查,但我宁愿保持类型安全。在不牺牲类型层次结构或类型安全的情况下,我能做些什么来实现这一点?请注意,在构造函数中传递策略不是对我来说是一个选项!在对象的生命周期内必须可以多次调用 foo。
编辑:
我意识到,如果不了解周围的情况,这个问题可能很难理解。我在这里打开了一个更详细的问题来解释我的问题的背景:How to make this Strategy-Object pattern type safe
【问题讨论】:
-
我认为你过度封装
Strategy;因为现在你的策略与你调用它的对象特别相关。您只需将调用该方法的对象传回即可。到时候简直是浪费。你想用实际的背景问题来实现什么? -
我将把它用于高级事件 -> UI 框架的动作系统。策略接口是响应键输入、鼠标移动、拖放、复制和粘贴等事件所采取的操作的替代。例如,TopLevelClass 将是某种抽象小部件。 MidLevelClass 将是一个具有复制和选择操作的集合组件。 LowLevelClass 将是一个带有箭头键移动操作的列表。
标签: java generics inheritance type-safety