• ベストアンサー

スーパークラスのインスタンスをサブクラスにアップキャスト

↑したい場合はどうしたらいいでしょうか。 データ構造体(beans)なのでスーパークラスのgetterとsetterを 利用してサブクラスに再構築する方法が考えられますが どうも腑に落ちないので質問してみました。 サブクラス側で継承をやめて集約にするにしても getterとsetterをまた書くの?って感じでわずらわしいです。 (jsp:getPropertyを利用するかもしれませんしね) さらにスーパークラスのメソッド全てをインタフェース化してサブクラスで実装とかしてたら具合が悪くなってきます。 この長年の疑問に終止符を打ってくれる方はいませんか?

質問者が選んだベストアンサー

  • ベストアンサー
  • takaP-
  • ベストアンサー率79% (83/105)
回答No.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)は提示された物そのままで動くと思います。 もし見当はズレな回答でしたらゴメンナサイ。 「こんなことせんでも・・・」という方が居られましたら補足・訂正・助言を下さい。私の勉強にもなりますので。

KaZtoYou
質問者

お礼

斬新な発想ですね。とても参考になります。Field#get がprivateも参照できるとは・・・盲点でした。 public staticなメソッドとしてユーティリティのよう な形で実装すると良いように感じました。また、多重継 承にも対応させるためClass#getSuperclassで再起呼び 出しすればスーパークラスをいじる必要もなくなります しまさに理想的といえます。 Stringクラスだけならいいですがシャローコピーか ディープコピーを取るかは意見の分かれる所でしょうか。 staticなフィールドや循環参照、インナークラスが 不安要素であり不確定要素に感じました。この辺はも ちっと勉強します。 もしかしたらデザインパターンとか駆使して簡単にでき ちゃったりするのかもしれませんが言語仕様の不足をテ クニックでカバーしているみたいで個人的にとても好き です。 本当にありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.2

class AClass{...} class BClass extends AClass{...} ... AClass x = new AClass(); のとき、 BClass y; y = (BClass)x; にしたいということでしょうか? とすると、不可能です。 これが AClass x = new BClass(); BClass y = (BClass)x; なら可能ですが、 最初にAClassとして作った場合はできません。 やると例外が出ます。

KaZtoYou
質問者

補足

はじめはAClassで事足りていたけど後からやぱり拡張されたBClassに変更したいというのが世の常、人の常ってなもんです。

全文を見る
すると、全ての回答が全文表示されます。
  • takaP-
  • ベストアンサー率79% (83/105)
回答No.1

ちょっと質問の意味が解かりません。 できれば、もう少し具体的に補足願えないでしょうか。

KaZtoYou
質問者

補足

言葉で説明するのは難しいものですね。 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()); としなければならないでしょう。しかし、フィールドが増えるにつれて 面倒さが飛躍的に増大します。この点が何とかならないか思案している次第です。 よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • サブクラス型オブジェクトをスーパークラス方に代入

    ある所で下記のような継承についての記述をみつけました。 ----------------------------------------------------------------------------- 継承の目的は、あるクラスで実装したメソッドなどの機能を利用して、 さらに実装を追加する差分コーディングです。 一つのクラスから複数のサブクラスを作ることも良くあります。 このような時、それらのサブクラス型オブジェクトの参照を代入できる変数として、 スーパークラス型変数を使うことがしばしばあります。 ----------------------------------------------------------------------------- サブクラス型オブジェクトの参照を代入できる変数として、 スーパークラス型変数を使うことがある、と いうのはどういった場合に使うのでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Java
  • PHPでサブクラスからスーパクラスのprivate

    メンバにアクセスできる件について PHPでスーパークラスで定義したprivateのメンバにサブクラスからアクセスできる件について 質問です。 class TestClass { private $value01 = "スーパークラスの private メンバ"; public function testMethod01 () { print "スーパークラスのパブリックメソッド"; print "<h1>{$this->value01}</h1>"; } protected function testMethod02(){ print "スーパークラスの protected メソッド"; } private function testMethod03(){ print "スーパークラスの private メソッド"; } public function getMethodList(){ print_r(get_class_methods($this)); } } class ExClass extends TestClass{ private $value01 = "サブクラスの private メンバ"; } $obj = new ExClass(); $obj-> testMethod01(); と上記のようにサブクラスのインスタンスから継承したpublicなメソッド testMethod01()を実行すると スーパークラスのprivateなプロパティにアクセスできてしまいます。 これってどういうことでしょうか?privateメンバってそのクラスの中からだけしかアクセスできませんよね? 上記では、サブクラスからアクセスしているような状態にみえますがどういうことでしょうか? ご教授御願い致します。

    • ベストアンサー
    • PHP
  • スレッドセーフなクラスのサブクラスは? synchronizedって継承先では?

    1)メソッドにsynchronizedキーワードをつけた時、継承先のサブクラス側でもsynchronizedは生きているのでしょうか? 2)もし生きていると サブクラス側で、synchronizedをとりけしたい場合 synchronizedをつけない形でオーバーライドして 中身の実装は super.メソッド名(); だけにするという方法しかないということでしょうか? 3)なお、 サブクラス側で、synchronizedキーワードを追加しながら メソッドのオーバーライドができるということは 知っています。 4) (1)の答えが生きていない。とすれば・・。 スレッドセーフなクラスをがんばって作成しても、 サブクラス作成者がいちいち意識しなければ、 サブクラスはスレッドアンセーフになってしまう ということでしょうか? サブクラス作成者がたとえ、赤の他人でまったく、 コミュニケーションをとれない状況であろうとも、 そうならないようにするためのしかけを 作るためのテクニックはあるでしょうか? なお、これはクラスをfinalしたくない場合の話です 以上です。

    • ベストアンサー
    • Java
  • サブクラスでセッターを呼び出す

    java初心者です。 以下のようなソースコードで、コンパイルしたらエラーが出ました。 サブクラスのsetterのところでエラーが出たんですが、 サブクラスでスーパークラスのメソッドは呼び出せないんでしょうか? それとも他に間違いがあるんでしょうか? class rensyu { private int x; rensyu(){ x=this.x; } int getX(){ return x; } void setX(int m){ this.x = m; } } class rensyu2 extends rensyu{ private rensyu[] A; rensyu2(){ A = new rensyu[100]; } int getter(int i){ return A[i].getX(); } void setter(int x,int i){ A[i].setX(x); } } class rensyuTester{ public static void main(String[] args) { rensyu2 A = new rensyu2(); A.setter(1,0); A.setter(2,1); System.out.println(A.getter(0) +" "+ A.getter(1)); } }

    • ベストアンサー
    • Java
  • スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラム

    スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラムでつまずいています。 Aを継承したB、Cクラスのインスタンスを作成し、スーパークラスであるA型の配列asにまとめます。 それからループでas[i]にはいっている各インスタンスのメソッドを使いたいのですが、 スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。 BとCを同じ配列に保存し、かつそれぞれのmethod()を実行したい場合どのようにしたら良いのでしょうか。 ご教授ください、どうぞよろしくお願いします。 class Main{ private B b; private C c; private A[] as = new A[2]; void mainMethod(){ as[0] = b = new B(); as[1] = c = new C(); for(int i=0; i<3; i++){ as[i].method(); } } } class A{} class B extends A{ void method(){ System.out.print("It is B"); } } class C extends A{ void method(){ System.out.print("It is C"); } }

  • データベース(テーブル情報)操作方法に関して

    まだJAVAを初めて1ヶ月ちょいの初心者です。ぜひ教えて頂きたいことがあります。 データベースのテーブル操作に関してなんですが、どうコーディングしたら効率のよいプログラムになるのか検討段階でつまずいています。 今考えているのが、スーパークラスにてテーブルの各カラム変数を宣言し、そのサブクラスにてテーブル操作毎のSQL発行(スーパークラスから継承した抽象メソッドを用いて)をしたほうがいいのかなと考えてます。 つまり・・・ ----<<super class(抽象クラス)>>----- public abstract class InfoTable { private String name; private int age; : public String getName() { return Staff_ID; } public String setName(String name){ this.name = name } //抽象クラス(SQLを発行しテーブルを操 //作する抽象メソッド) public abstract boolean exec(); } とし、サブクラスにて継承&実装すればよいのかと・・・。 実際にテーブルのカラムが多くなれば、setter・getterを多く繰り替えし処理をしなければならなくなり、それは大変だし、プログラム的にもよくないんじゃないかと考えています。実際にサブクラスはサーブレットからデータを取得してから処理を行う予定なので、Vectorを使えばいいのかなとは思いますが、どう使ったらよいのか検討がつきません。 長々と書いてしまい申し訳ございません。 どなたか良い知恵をお貸し下さい!

    • ベストアンサー
    • Java
  • 継承について

    下の質問の回答、間違ってませんか? -------------------------------------------- 親クラスのフィールドをメソッドを全て継承することになります。よって、サブクラス2は、サブクラス1とスーパークラスのメンバーを全て持つことになります。サブクラス2をインスタンス化すると、サブクラス1とスーパークラスが全てインスタンス化(コンピューターのメモリ上等に配置)されます。 ただ、可視性というものがあり、サブクラスから親クラスのメンバーを直接取り扱えない場合があります。privateや可視性修飾子無しの場合、サブクラスから直接取り扱えません。ただ、継承はされているので、インスタンスとしては存在します。例えば、 class スーパークラス{ private int abc; public int getAbc(){ return this.abc; } というクラスがあり、これを継承したサブクラスがあったとします。 サブクラスからは、privateなメンバー変数abcは直接取り扱うことができません。ただ、publicなgetAbcメソッドはサブクラスから取り扱えます。これで何が分かるかといいますと、privateなメンバーでもサブクラスに継承されるのです。単に可視性の問題で直接取り扱えないだけなのです。 また、オーバーライドされたメソッドがあったとしても、super.メソッド()で親のメソッドも呼べますので、これも継承されているのです。

  • [Obj-c]元クラスからサブクラスのメソッド

    Objective-Cの勉強をしています。 ClassAは元クラス(スーパークラス)です、 ClassB1、B2はClassAを継承(サブクラス)しています。 ClassAとClassB1にはiMethodというメソッドが存在します。 最下部にソースと実行結果があります。 ●そこで質問なのですが、  ClassAのインスタンスにClassB1のインスタンスをセットすると、  同じ名前のメソッドがあるだけでなぜClassB1のメソッドが呼ばれるのでしょうか?  (下記ソースの[bangai iMethod]; の部分です。)  ClassB1のインスタンスを渡すとClassAのインスタンスが  ClassB1のメソッドを使用できる理由がわかりません、  継承しているとはいえ型が違うものを参照渡しできる理由も今ひとつわからないです。  またこれはどういう機能を言うのでしょうか?  (例えば ポリモーフィズム、動的バインディングなど) ★ソース ------------------------------------------------------------------------------ #import <Foundation/Foundation.h> // ClassA @interface ClassA : NSObject { } @end @implementation ClassA -(void) iMethod { NSLog(@"スーパークラスのインスタンスメソッドです。\n"); return; } @end // ClassB1 @interface ClassB1 : ClassA @end @implementation ClassB1 -(void) iMethod { NSLog(@"サブクラスのインスタンスメソッドです。\n"); return; } @end // ClassB2 @interface ClassB2 : ClassA @end @implementation ClassB2 @end int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... ClassB1 *instance_B1 = [[ClassB1 alloc]init]; ClassB2 *instance_B2 = [[ClassB2 alloc]init]; [instance_B1 iMethod]; [instance_B2 iMethod]; // 親には子のクラスが入れられる ClassA *bangai = instance_B1; [bangai iMethod]; } return 0; } ------------------------------------------------------------------------------ ★実行結果 サブクラスのインスタンスメソッドです。 スーパークラスのインスタンスメソッドです。 サブクラスのインスタンスメソッドです。

  • 継承(extends)について

    extendsについてわからないことがあります。 次の3つのクラスがあった時、 class スーパークラス { ... class サブクラス1 extends スーパークラス { ... class サブクラス2 extends サブクラス1 {... サブクラス2は、サブクラス1でスーパークラスから継承しているフィールドをメソッドを継承するのでしょうか?

    • ベストアンサー
    • Java
  • インターフェースとサブクラスはどっちを使えばいい?

    ある機能Aを持ったクラスを作りたいとき、次の二つの方法があると思います。 (1) サブクラス → 機能Aを持ったクラスを拡張したサブクラスを作る。 (2) インターフェース → 機能Aを実現するメソッドをまとめてインターフェースにし、そのインターフェースを実装するクラスを作る。 これらの使い分けはどうすればよいのでしょうか?つまり、どういうときに(1)を使ってどういうときに(2)を使えばよいのでしょうか? 私が現在思いつく(1)と(2)の違いは以下の二つです。 ・(1)の方法は手軽 ・(1)の方法だと、一つのクラスの拡張しかできない これくらいでしょうか。もっと本質的な違いはあるのでしょうか?

    • ベストアンサー
    • Java