- - PR -
自作クラスでObjectクラスのメソッドを使用したい。
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-07-06 18:44
自作クラスで、Objectクラスのcloneメソッドを利用したいのですが、うまくいきません。
自作クラスで、オブジェクトを一つ生成し、そのオブジェクトのコピーを作成したいと考え、cloneメソッドを利用しようとしています。 ――――――――――――――――――――――――――――――― //車クラス class Car{ int num; double gas; //↓コピーを作成するメソッド static Car copy(Car car1)throws CloneNotSupportedException{ return (Car)car1.clone(); } } //車クラスのインスタンスを作成する class Sample1{ public static void main(String args[])throws CloneNotSupportedException{ Car car1; car1 = new Car(); car1.num = 1234; car1.gas = 20.5; Car car2; car2 =Car.copy(car1);//コピーを作成するメソッドを呼び出す System.out.println("車のナンバーは"+ car1.num + "です。"); System.out.println("ガソリン量は"+ car1.gas + "です。"); System.out.println("車のナンバーは"+ car2.num + "です。"); System.out.println("ガソリン量は"+ car2.gas + "です。"); } } ――――――――――――――――――――――――――――――――――― コンパイルはできて、実行時にエラーが出ます。 エラーは下記です。 Exception in thread "main" java.lang.CloneNotSupportedException: Car at java.lang.Object.clone(Native Method) at Car.copy(Sample1.java:6) at Sample1.main(Sample1.java:19) ――――――――――――――――――――――――――――――――――― ――――――――――――――――――――――――――――――――――― どうか、よろしくお願いいたします。 | ||||||||
|
投稿日時: 2005-07-06 18:46
自分でCarのclone()を実装する必要があります。
| ||||||||
|
投稿日時: 2005-07-06 18:50
http://www.nurs.or.jp/~sug/soft/java/java23.htm
↑このあたりに書いてあります | ||||||||
|
投稿日時: 2005-07-06 19:18
おかけ様で、完成しました!
ありがとうございました。 作成して、出てきた疑問なのですが、 結局、コンストラクタも作成しなければならないのですね? あまり、このような事はしないのでしょうか。 同じインスタンスを生成するならば、クラスを作成して初期値を入れておいたらよい ということでしょうか? 完成したプログラムですが、無駄は多いのでしょうか。 もっと簡略化して書けるのでしょうか? ―――――――――――――――――――――――――――――――――― ―――――――――――――――――――――――――――――――――― class Car implements Cloneable{ int num; double gas; Car(Car car1){ num = car1.num; gas = car1.gas; } Car(){} static protected Car clone(Car car1){ return new Car(car1); } } class Sample1{ public static void main(String args[])throws CloneNotSupportedException{ Car car1; car1 = new Car(); car1.num = 1234; car1.gas = 20.5; Car car2; car2 = Car.clone(car1); car1.num = 0000; car2.gas = 10.0; System.out.println("車のナンバーは"+ car1.num + "です。"); System.out.println("ガソリン量は"+ car1.gas + "です。"); System.out.println("車のナンバーは"+ car2.num + "です。"); System.out.println("ガソリン量は"+ car2.gas + "です。"); } } ―――――――――――――――――――――――――――――――――― ―――――――――――――――――――――――――――――――――― | ||||||||
|
投稿日時: 2005-07-06 19:34
無駄がないかと言われれば、numとgasを違う値にするのにcar2をクローンで生成することが無駄そのもののような(笑)
自分とmogeさんの心づもりとしては、
こんな感じです。 コンストラクタを増設したくないなら、
こんなんで。 | ||||||||
|
投稿日時: 2005-07-06 19:38
ディープコピーの必要がなければ、実装は不要です。
これだけで、クローンの作成が可能ですが 参照型のフィールドを持つ場合は、 そのフィールドの参照まではクローンの対象とはなりません。 | ||||||||
|
投稿日時: 2005-07-06 19:42
なぜこのような結論になるんですか? これだとClonableは関係ないですよね。
Object#cloneを利用できるようにするために必要なのは、 ・Clonableインタフェースを実装すること ・cloneメソッドをオーバライドすること です。実際には以下のようなコードになります。利用側のコードはご自分で考えてください。
| ||||||||
|
投稿日時: 2005-07-06 20:23
スーパークラスの#clone()を呼び出した方がいいのではないでしょうか?
numとgasはプリミティブ値なので、かつのりさんご指摘のように、これだけなら ディープコピー実装は不要ですね。 上記例のように、ミュータブルオブジェクト(状態が変化しうるオブジェクト)を フィールドに持つ場合は、それを再帰的に#clone()しないと、完全な ディープコピーにはなりません。 イミュータブルオブジェクト(StringやInteger等、状態が変化しないオブジェクト)で あれば、再帰的に#clone()しなくても、問題になりません。 書籍 Effective Java 等に詳細な説明があります。 |