【发布时间】:2009-08-30 11:01:34
【问题描述】:
我正在编写一个需要类来实现 clone() 方法的接口。我对此的天真做法是这样的:
public interface ISolvableGame {
function clone():ISolvableGame;
//...
}
其他地方:
public class MyGame implements ISolvableGame {
public function clone():MyGame {
// ...
}
}
我原以为这种签名是合法的,因为MyGame.clone() 返回了一个实现 ISolvableGame 的类的实例,在我看来这满足了接口中的约定。然而,像上面这样的代码会产生一个编译错误,指的是MyGame.clone() 的签名与接口中指定的签名不同。
因此,我的问题是,如果实现的方法必须与接口中的签名完全匹配,我如何制作需要克隆方法的接口?显然,使界面更具体没有任何意义。但是,如果我使实现的方法不那么具体(即,如果我键入 MyGame.clone() 作为返回 ISolvableGame),该克隆方法的其他用户将不再知道他们得到了什么。
我是否需要两个版本的克隆方法,一个键入为ISolvableGame 以满足接口,另一个键入为MyGame 用于在类中使用?还是有更好的方法?
注意: 我正在使用 ActionScript3(一种实现 ECMA4 规范的类 Java 语言)。我将其标记为与语言无关,因为假设 AS3 在处理接口的方式上并不是独一无二的。但如果我上面的示例代码适用于其他语言,那么我的问题可能是我的语言所特有的。
更新:我突然想到检查我的语言的核心库是如何处理这个问题的。例如,有一个IEventDispatcher 接口,它定义了一个方法dispatch():Event - 所以任何调度Event 的子类 的类都无法实现IEventDispatcher,这最终类似于我的问题.
核心库通过从类EventDispatcher 中继承 来处理这个问题,该类的存在是为了实现IEventDispatcher。从而获得编译时类型安全,但代价是一开始就淡化了使用接口的意义,因为人们通常更喜欢接口来避免继承带来的问题。
我认为我的选择是:
- 最终依赖继承,就像核心库所做的那样
- 实现 Frederik 描述的两种方法,但名称不同
- 按照 James 的描述牺牲编译时类型安全
答案: 最后,我选择让接口指定cloneToSolvable 方法 - 即,接口指定克隆到接口类型的方法,实现类必须除了他们可能拥有的任何更具体类型的克隆方法之外,还拥有该方法。在我看来,这是最不令人不快的选项。
【问题讨论】:
标签: actionscript-3 language-agnostic interface methods clone