- ベストアンサー
Javaの継承について
- JavaのクラスAとBがクラスCを継承しており、Aのインスタンスを生成しCの変数に値を設定します。しかし、この設定した情報をBのインスタンスに一括で設定することは可能でしょうか?
- Aに設定した情報をBにコピーする方法はありますか?すべてのsetterを呼び出して設定するのは面倒です。
- AとBはクラスCを継承しており、Aのインスタンスを生成しCの変数に値を設定したいが、Bのインスタンスに一括で設定する方法が知りたい。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
7の人への補足で、あなたのやりたいことが何となくわかってきましたよ。 継承にこだわるのであれば、リフレクションで以下のように解決できます。 public static void main(String[] args) throws Exception{ A a = new A(); a.setX(100); a.setY("きのこの山"); a.setZ("たけのこの里"); B b = new B(); copyField(a, b); System.out.println(String.format("x:%d, y:%s, z:%s", b.getX(), b.getY(), b.getZ())); } private static void copyField(C a, C b) throws IllegalAccessException { Field[] fields = C.class.getDeclaredFields(); for(Field f : fields) { f.set(b, f.get(a)); } } もしくは、A/BとCの関係を継承ではなく委譲で解決すると Cのインスタンスを普通にcopyするだけで済むのですよ。 こちらの方が汎用性があるのでわたしは好きです。
その他の回答 (7)
- satomi3951
- ベストアンサー率71% (98/137)
スーパークラスにコピー用のメソッド用意したら? public class C { private int x; private int y; public void assign(C src) { this.x = src.x; this.y = src.y; } public int getX() { return x }; public void setX(int x) { this.x = x }; public int getY() { return y }; public void setY(int y) { this.y = y }; } public class A extends C { } public class B extends C { } A a = new A(); a.setX(1); a.setY(2); B b = new B(); b.assign(A);
Observer パターンだな
- nda23
- ベストアンサー率54% (777/1415)
リフレクションを使えば、クラスのメンバが取得できます。 for文で、メンバを順に抜き出し、Invokeでセッタ/ゲッタを 実行すれば目的のものができるでしょう。 クラスの定義が変更されても、この部分は修正不要です。 ユーティリティなどのように、パラメータのオブジェクト型が 特定できないメソッドではリフレクションによって、メンバの 名前や属性を調べて処理する例が結構あります。 また、指定によってはprivateなメンバまで見えます。 キーワード「リフレクション」でググってみてください。
- Tacosan
- ベストアンサー率23% (3656/15482)
ああそうか, #2 を読んで気づいたんだけど「この設定した情報をBのインスタンスに一気に設定する」が実はあいまいなのか. つまり ・それ以降に作る B のインスタンスに設定する (それ以前に作ったものは無視) ・とにかくすべての B のインスタンスに設定する のかが区別しきれない. #1 は表現をぼかしたので結果的にどちらにも対応しちゃってるけど, 前者を期待するなら (B または C にコンストラクタを書いたうえで) A をファクトリとする (だからもちろん継承関係は存在しない) のが正しいのかもしれない.
- いけだ ひろし(@ike-2000)
- ベストアンサー率53% (69/129)
オブジェクトを本当にコピーする必要があるのであればcloneの実装であろうと思います。 Cloneable、Object.clone()メソッドを参照してください。 ※邪道な方法としてはRMIを使えばコピーが渡るはずです。
- 渡辺 まいたん(@maitan0715)
- ベストアンサー率58% (10/17)
質問そのものについての回答としては、 Bクラスにコンストラクタを定義することで解決すると思いますよ。 class B extends C{ public B( int x, String str) { this.x = x; this.str = str; } } A a = new A(); a.setStr("aaa"); a.setInt(5); B b = new B( a.getInt(), a.getStr() ); // getInt() や getStr() はprivate でない前提 ただ、他の回答者の方も指摘しているとおり、 あなたが何故「継承」を使っているのかが全然分かりません。 おそらく、「クラス」「インスタンス」「継承」など、 オブジェクト指向の理解が不十分なのだと思うのですよ。 あなたの質問内容を普通に書けば、下のようなプログラムになるはずで 継承を使う必要性が全くないのです。 class C { int x = 0; String str = ""; public C() { } public C( int x, String str) { this.x = x; this.str = str; } void setInt(int x){this.x=x;} void setStr(String str){this.str=str;} int getInt(){return this.x;} String getStr(){return this.str;} } class Program { public static void main(String[] args) { C a = new C(); a.setStr("aaa"); a.setInt(5); C b = new C( a.getInt(), a.getStr() ); } } 「やさしいJava」などの入門書を1度読んでみることをお勧めします。
- Tacosan
- ベストアンサー率23% (3656/15482)
A や B のメソッドに仕込んでおけばできると思うけど, 何を目的としてそういうことをしたいのかが想像できない.... 特に「A で設定しているにもかかわらず, A のインスタンスにではなく B のインスタンスに影響する」ってのが謎な感じ. A のインスタンスに反映されるならわからんでもないんだけど.
補足
質問内容に補足します。 ・例としては設定する値は2つですが実際は100個くらいあります。 ・例の実装方法でOKだがもっと簡単にやる方法はないかという質問になります。 ・理由が分からない等の回答がありますが、例は分かりやすく簡略化したものであるため分かりにくくなってしまったかもしれません・・・ やりたいことは継承している情報のみを取りだして設定する方法になります。