最初の簡単な質問: なぜ にsuper.clone()
キャストされるのMyClass
ですか? これは、 の宣言がHerClass.clone()
の戻り値を指定したHerClass
ためです。そのため、正しい型にキャストする必要があります。
さて、より難しい質問:super.clone()
実際に のインスタンスを返すにはどうすればよいMyClass
でしょうか? 私は実際に答えを見つけるのに苦労しましたが、Joshua Bloch の「Effective Java」で答えを見つけることができました。Object.clone()
その背景にはまだよくわからない「魔法」があります。
本のアイテム11:
実際には、プログラマーは、クラスを拡張してサブクラスから super.clone を呼び出すと、返されるオブジェクトはサブクラスのインスタンスになると想定しています。スーパークラスがこの機能を提供できる唯一の方法は、super.clone を呼び出して取得したオブジェクトを返すことです。clone メソッドがコンストラクターによって作成されたオブジェクトを返す場合、そのオブジェクトのクラスは間違っています。したがって、非 final クラスで clone メソッドをオーバーライドする場合は、 super.clone を呼び出して取得したオブジェクトを返す必要があります。クラスのすべてのスーパークラスがこの規則に従う場合、super.clone を呼び出すと、最終的に Object の clone メソッドが呼び出され、適切なクラスのインスタンスが作成されます。
私はもともと、あなたが常に を呼び出さなければならないことを知らずに、プログラムを書くことであなたの質問に答えようとしましたsuper.clone()
。私の自作の clone メソッドは、コンストラクター ( ) から生成されたHerClass
の新しいインスタンスを返していました。コードはコンパイルされましたが、キャストしようとしたときに実行に失敗しました。サブタイプの 1 つのインスタンスである値を返すことができるのは、チェーンされたメソッドだけです。HerClass
new HerClass()
(MyClass) super.clone()
Object.clone()
HerClass.clone()
ifが明示的に実装されていない場合、デフォルトでは単純に を返すことに注意してくださいObject.clone()
。デフォルトのメソッドにはprotected
アクセスがありますが、サブクラスから呼び出しているので問題ありません。