clone() メソッドを実装するクラスを必要とするインターフェイスを作成しています。これに対する私の素朴なアプローチは、次のようなものでした。
public interface ISolvableGame {
function clone():ISolvableGame;
//...
}
他の場所:
public class MyGame implements ISolvableGame {
public function clone():MyGame {
// ...
}
}
MyGame.clone()
ISolvableGame を実装するクラスのインスタンスを返すため、この種の署名は合法であると想定していましたが、これはインターフェイスの契約を満たしているように思えます。ただし、上記のようなコードMyGame.clone()
は、インターフェイスで指定されたものとは異なるシグネチャを持つという事実を参照して、コンパイル エラーを生成します。
したがって、私の質問は、実装されたメソッドがインターフェイスのシグネチャと正確に一致する必要がある場合、クローン メソッドを必要とするインターフェイスを作成するにはどうすればよいかということです。明らかに、インターフェイスをより具体的にしても意味がありません。しかし、実装されたメソッドの具体性を低くすると (つまり、 return と入力MyGame.clone()
した場合ISolvableGame
)、そのクローン メソッドの他のユーザーは、何を取得しているのかわからなくなります。
clone メソッドの 2 つのバージョンが必要ですか? 1 つISolvableGame
はインターフェイスを満たすように型付けされ、もう 1 つMyGame
はクラス内で使用するために型付けされますか? または、より良いアプローチがありますか?
注:私は ActionScript3 (ECMA4 仕様を実装する Java に似た言語) で作業しています。AS3 はインターフェースの扱い方が独特ではないという前提で、これを言語に依存しないというタグを付けました。しかし、上記のサンプル コードが他の言語で機能する場合、問題はその言語に固有のものである可能性があります。
更新: 私の言語のコア ライブラリがこれにどのように対処しているかを調べてみることにしました。たとえばIEventDispatcher
、メソッドを定義するインターフェイスがあるため、サブクラスをdispatch():Event
ディスパッチするクラスは実装できません。これは最終的に私の問題に似ています。Event
IEventDispatcher
コア ライブラリは、実装目的で存在するクラスからそのようなクラスを継承させることで、これに対処します。したがって、コンパイル時の型の安全性が得られますが、継承によって引き起こされる問題を回避するために通常はインターフェイスを好むため、そもそもインターフェイスを使用するポイントがかなり希薄化するという犠牲が伴います。EventDispatcher
IEventDispatcher
私の選択は次のとおりだと思います。
- コア ライブラリが行うように、最終的に継承に依存する
- Frederik が説明するように、名前の異なる 2 つのメソッドを実装します。
- James が説明するように、コンパイル時の型の安全性を犠牲にする
回答:最終的に、インターフェイスでメソッドを指定するオプションを使用しました。cloneToSolvable
つまり、インターフェイスは、インターフェイス タイプに複製するメソッドを指定し、実装クラスには、より具体的に型指定された複製メソッドに加えて、そのメソッドが必要です。持っているかもしれません。これは、オプションの中で最も不快ではないように思えました。