- - PR -
Widening
1|2|3
次のページへ»
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2003-04-21 23:31
ものすごく簡単な質問かもしれないのですが、思い付かなかったもので
教えていただければ幸いです。 あるclassには、多く(仮に10個)のフィールドがあります。 class A { private Object field1; : private Object field10; } そのclassを継承し、フィールドを新たに1個加えたclassを作ります。 class B extends A { private Object fieldX; } getter()、setter()メソッドは省略 class Aのフィールド値をclass Bにコピーし(あるいは参照させ)、 新たに加えた値をセットして、新しいデータとしたいのですが、どの ようにすればスマートなのでしょうか。 言いたいことがうまく伝えられなくて、申し訳ないのですが、イメー ジ的には、こんな感じです。 A aObject = new A(); aObject.setField1(f1); : aObject.setField10(f10); // ここからがやりたいこと B bObject = (B)aObject; // <-当たり前ですが、ClassCastException bObject.setFieldX(fX); できれば、全フィールドコピーしてから、新たに加えた値をセットす るのは、class Aのフィールドを追加した際、フィールドのコピー処 理も追加しなければいけないので、避けたいです。 いろいろ調べて、...(あさっての方向を見てるかもしれない) リフレクションを使う手もありますが、スマートじゃない気がします (遅そうですし)。 Serializeが関係ありそうな気がしますが、ファイルに一旦書き出し たりしたくないです。 過去のclone()の書き込みなども見てみたのですが、混乱してしまい ました。 より敷くお願いします。 |
|
投稿日時: 2003-04-22 08:50
ちょっと外しているかもしれませんが、継承ではなく
クラスBでクラスAをラップするようにしては? class B { private A a; private String field; public B(A a){ this.a = a; } public void setField(String s){ ... } public String getField(){ ... } // aへの転送メソッドを列挙 } 使うときは A a = new A(): a.setXxx( ... ); .... B b = new B(a); b.setField( ... ); のような感じで。 [ メッセージ編集済み 編集者: YOU@IT 編集日時 2003-04-22 08:51 ] |
|
投稿日時: 2003-04-22 17:31
> // ここからがやりたいこと
> B bObject = (B)aObject; // <-当たり前ですが、ClassCastException > bObject.setFieldX(fX); ここでClassCastExceptionだと分かってらっしゃるみたいなので、 B のオブジェクトを作って持ち回り、必要なところで A aObject = (A)bObject; というのはいかがでしょう? class A の変更は class B の変更を必要としません。 はずしてないといいですが。 ずれてそうなら、もう少し状況をくださいな。 |
|
投稿日時: 2003-05-01 14:01
初めまして、デビュー投稿になります。
Aにcopy()メソッドを実装しておいて、Bのコンストラクタで呼び出すのはどうですか? ※以下、かなり端折ってますが・・・ class A { private Object field1; private Object field2; public copy(A org) { this.field1 = org.field1; this.field2 = org.field2; } } class B extends A { private Object fieldX; public B(A a) { copy(a); } } 使い方はYOU@ITさんと同じです。 A objA = new A(); objA.setField1(...); objA.setField2(...); B objB = new B(objA); objB.setFieldX(...); |
|
投稿日時: 2003-05-01 18:09
それは厳密にはcopyとは違いますね。
field1とfield2はプリミティブではなくオブジェクトですから、 参照渡しになります。 しかし用途としては間違ってないと思いますので、 copyをcastなどのメソッド名称にすることをお勧めします。 |
|
投稿日時: 2003-05-01 18:23
ちょっと邪道かもしれないですが、
Jakarta CommonsのBeanUtilsを使うってのはどうでしょう? org.apache.commons.beanutils.BeanUtils.copyProperties(java.lang.Object dest, java.lang.Object orig)で 異なるインスタンスで同じ名前のプロパティをコピーできます。 (getter,setterがあることが条件) フィールド数が多いときとか、BのサブクラスのCでも同じことがやりたくなったり した場合に有効だと思うのですが。 |
|
投稿日時: 2003-05-01 18:33
そうですね。
フィールド数が多いときは、開発効率を考えるとBeanUtilsを使うのがいいと思います。 ただし、reflectを使っているのでパフォーマンスを気にする時には 使わないほうがいいでしょう。 |
|
投稿日時: 2003-05-04 14:46
レスポンスが遅くなりまして、誠に申し訳ございません。
皆さんのご意見、非常に参考になりました。ありがとうございました。 結論としては、クラスAにcopy(cast)メソッドをつくりました。 以下、時間が経ってしまい非常に心苦しいのですが、念のためお返事 させていただきます。 −−−− YOU@IT様 >ちょっと外しているかもしれませんが、継承ではなく >クラスBでクラスAをラップするようにしては? aへの転送メソッドを列挙しなければいけない点が、要件にあいません。 クラスAに変更(フィールドの追加や削除)があった際にコードを変更 したくありません。 HALcat様 >B のオブジェクトを作って持ち回り、必要なところで >A aObject = (A)bObject; この案は、最終的な逃げ道として使おうと思っておりました。 クラスAを使用する機能から、クラスBを使用する際の情報まで 見えてしまう点が、納得いっておりません。 HIR様 結論としては、この方法を採用しました(リフレクションを使って)。 しかし、本当はクラスAにcopy(cast)メソッドを追加したくない。 この操作はクラスAの機能ではなく、ユーティリティ的な扱いとしたい。 すごいわがままですね。> 自分 helmet様 zaxx_MD様 >Jakarta CommonsのBeanUtilsを使うってのはどうでしょう? 調査の過程で、気がついたらこれと同じ物を自分で作ってました。 なぜ、getter,setterがあることが条件でなければならないのかが 疑問でしたが、フィールドがprivateだから、ユーティリティクラス からアクセスする際、getter,setterがひつようなのですね。 独り言 streamをつかってクラスAからクラスBに出力できないかな? −−−− 皆さん、ありがとうございました。 |
1|2|3
次のページへ»
