- ベストアンサー
スーパークラスのインスタンスをサブクラスにアップキャスト
↑したい場合はどうしたらいいでしょうか。 データ構造体(beans)なのでスーパークラスのgetterとsetterを 利用してサブクラスに再構築する方法が考えられますが どうも腑に落ちないので質問してみました。 サブクラス側で継承をやめて集約にするにしても getterとsetterをまた書くの?って感じでわずらわしいです。 (jsp:getPropertyを利用するかもしれませんしね) さらにスーパークラスのメソッド全てをインタフェース化してサブクラスで実装とかしてたら具合が悪くなってきます。 この長年の疑問に終止符を打ってくれる方はいませんか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
これ以上に的確な回答が存在するかもしれませんし、そもそも意図する回答ではないかもしれませんが。。。汗 スーパークラスの記述変更は可能なのですよね? でしたら、子クラス(継承クラス)を通して、「親クラスで定義されているフィールド」を引数で渡される親クラスと同型(インスタンス自体は別の)のフィールド値に変更すれば何とかなりそうです。 どういった形で実装するかは自由なのですが、ソースコードを拝見した限りコンストラクタで操作をしたいようなので、今回はコンストラクタで値の変更をしてみます。。 import java.lang.reflect. * ; class Box { private String name; public Box() {} public Box(Box box) { try { Class c=box.getClass(); Field[] f=c.getDeclaredFields(); for(int i=0; i<f.length; i++){ f[i].set(this,f[i].get(box)); } } catch(IllegalAccessException e){} } public String getName() { return name; } public void setName(String name) { this.name = name; } } 他のクラス(ColorBox,Main)は提示された物そのままで動くと思います。 もし見当はズレな回答でしたらゴメンナサイ。 「こんなことせんでも・・・」という方が居られましたら補足・訂正・助言を下さい。私の勉強にもなりますので。
その他の回答 (2)
- liar_adan
- ベストアンサー率48% (730/1515)
class AClass{...} class BClass extends AClass{...} ... AClass x = new AClass(); のとき、 BClass y; y = (BClass)x; にしたいということでしょうか? とすると、不可能です。 これが AClass x = new BClass(); BClass y = (BClass)x; なら可能ですが、 最初にAClassとして作った場合はできません。 やると例外が出ます。
補足
はじめはAClassで事足りていたけど後からやぱり拡張されたBClassに変更したいというのが世の常、人の常ってなもんです。
- takaP-
- ベストアンサー率79% (83/105)
ちょっと質問の意味が解かりません。 できれば、もう少し具体的に補足願えないでしょうか。
補足
言葉で説明するのは難しいものですね。 class Box { private String name; public Box() {} public Box(Box box) { this=box; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class ColorBox extends Box { private String color; public ColorBox(Box box) { super(box); } } public class Main { public static void main( String[] args ) { Box a = new Box(); a.setName("a box"); ColorBox b = new ColorBox(a); System.out.println(b.getName()); } } これはうまくいかないけどthis=boxというところで感じをつかんでいただけたらと思います。本来ならthis.setName(box.getName()); としなければならないでしょう。しかし、フィールドが増えるにつれて 面倒さが飛躍的に増大します。この点が何とかならないか思案している次第です。 よろしくお願いします。
お礼
斬新な発想ですね。とても参考になります。Field#get がprivateも参照できるとは・・・盲点でした。 public staticなメソッドとしてユーティリティのよう な形で実装すると良いように感じました。また、多重継 承にも対応させるためClass#getSuperclassで再起呼び 出しすればスーパークラスをいじる必要もなくなります しまさに理想的といえます。 Stringクラスだけならいいですがシャローコピーか ディープコピーを取るかは意見の分かれる所でしょうか。 staticなフィールドや循環参照、インナークラスが 不安要素であり不確定要素に感じました。この辺はも ちっと勉強します。 もしかしたらデザインパターンとか駆使して簡単にでき ちゃったりするのかもしれませんが言語仕様の不足をテ クニックでカバーしているみたいで個人的にとても好き です。 本当にありがとうございました。