自作クラスの型にキャストする方法について

このQ&Aのポイント
  • クラスの型にキャストする方法やクラスの関係によるキャストの可否について説明します。
  • キャスト可能な関係にある場合、キャスト処理によってコンストラクタは呼ばれませんが、想定しているコールバック処理は行われることがあります。
  • クラスAAAとクラスBBBの格納場所の関係やキャストによるインスタンス生成についても解説します。
回答を見る
  • ベストアンサー

「自作クラスの型」にキャストする方法について。

「自作クラスの型」にキャストする方法について。 Java初心者ですが、よろしくお願いします。 class AAA class BBB ※クラスAAAはクラスBBBのスーパークラス(直属のスーパークラスとは限らない)とします。 class CCC という3つのクラスがあるとして、 この場合、 class CCC{ AAA var; BBB bbb; void test(){ bbb = new BBB(); var = (AAA)bbb; //---★ } } というような、キャストは可能ですよね?(←確認1) 次に(確認1に問題が無い場合)、 クラスAAAとクラスBBBの格納場所(パッケージ関連の話です)について、 AAAとBBBがどういう位置関係にあるときに、上記のキャストは可能になるのでしょうか? AAAとBBBが同一パッケージ内にある時だけでしょうか?(←確認2[質問の核]) で、さらに、 上記の「---★」の所で、 AAAクラスにキャストする処理をしていますが、 この時、AAAクラスのコンストラクタは呼ばれるのでしょうか? (AAAをnewしていないけれど、キャスト処理でnewしたのと同じことになったりしますか?) また、これと同様の質問になりますが、 仮に、クラスAAAの設計が、クラスAAAのインスタンスが生成された場合に、 何らかのコールバック処理が行われるような設計の場合、 この (AAA)bbb というキャストによって、想定しているコールバック処理 は行われたりしますでしょうか?(←確認3) 初心者らしからぬ質問かもしれませんが、 どなたか、どうか分かりやすく教えて下さい。

  • Java
  • 回答数3
  • ありがとう数6

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

> bbb = new BBB(); > var = (AAA)bbb; //---★ > というような、キャストは可能ですよね?(←確認1) わざわざ書かなくともキャスト無しで var = bbb; と代入できます。下の例も見てください。 var = new BBB(); //キャスト不要 bbb = (BBB)var; //キャスト必須 ANo.1の方が書いているとおり、簡単に試してみることができる内容ばかりなのであとは自力で確認してみてください。

nbsp0606
質問者

お礼

回答ありがとうございます。 NO.1のお礼の中でも書かせて頂いた通り、 テストプログラムを書いて検証しているところなのですが、 「確認3」の所は、(AAA)とキャストしたからと言って、 AAAがnewされるわけではなさそう、ということが分かってきました。 また、「確認1」は、書籍などから、おおかた正しいであろうと思っておりまして、 これも念のためテストプログラムにて検証し、問題なさそうだと分かってきました。 salsberryさんから頂いた回答も、大変勉強になりました。 で、問題の「確認2」ですが、 パッケージの異なるソースファイルの「コンパイル、実行」のあたりで、 つまづいていて、検証できずにおります。 ということで、こちらの問題をまず解決してきます!

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ま~確かに「試せばわかる」かもしれないけど, 究極的に「言語仕様としてそうなっている」のか, それとも「その処理系ではそうなっているけど言語としては保証されていない」のかは区別つかないんではないかな>#1&#2. Java の言語仕様って, (そうである「はず」のものは) 本屋にいけば見付かりますよね.

nbsp0606
質問者

お礼

回答ありがとうございます。 まだ私には難しい内容でしたが、なんとなく言わんとすることは分かります。 テストプログラムを的確に書ける方ですと、 そのあたりの高度な疑念が湧きそうですね。 初心者である私の場合、 まずは、自分の書いたテストプログラムが怪しい(笑)ので、 「このコードで、とりこぼしなく検証できているんだろうか」という疑念に しばしば悩まされます。 今はパッケージの異なる2~3のファイル(AAA、BBB、CCC)の コンパイル、実行あたりでつまずいております。(苦笑) がんばります!

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

簡単なテストプログラムを組めばすぐに分かることよ。 まずはやってみること。 その上で納得行かないなら質問して頂戴。

nbsp0606
質問者

お礼

回答ありがとうございます。 アドバイスを頂いた通り、テストプログラムを書き、 現在、検証しているところですが、 検証以前の所(パッケージ分け、コンパイル、実行の段階)でエラーが発生し、 こちらで停滞しております。 検証ができ次第、もし、疑問点がありましたら、補足を書かせて頂こうかと思っております。

関連するQ&A

  • キャストによるアドレス変更について

    多重継承クラスのインスタンスのポインタを基底クラスのポインタ に代入するとき、キャストで、vtableへのポインタを変更するために、 多重継承クラスのインスタンスのポインタのアドレスから4byte加算 したアドレスが、基底クラスのポインタに代入されます。 以下のプログラムは、多重継承ではないですが、pCのポインタの アドレスに4byte加算してpAに代入されます。pAのデストラク タはvirtual宣言していないので、pAが指すアドレスにはvtable のポインタはないはずですが、4byte加算するという動作が起こるのは 何故でしょうか。 #include <iostream.h> class AAA { public: AAA(){} ~AAA(){} }; class BBB:public AAA { public: BBB(){} virtual ~BBB(){} }; class CCC:public BBB { public: CCC(){} ~CCC(){} }; int main(void) { CCC *pC = new CCC(); AAA *pA = (AAA *)(pC); delete pA; return 0; }

  • クラスの使い方

    php5です。 --- test1.class.php --- class TEST1 { function hoge1() { // 実際に複雑な処理ですが概要として簡易化してます $aaa = 'hoge1'; // クラスの実行で単純に戻り値を返す return $aaa; } } --- test2.class.php --- class TEST2 { function hoge2() { // 実際に複雑な処理ですが概要として簡易化してます $bbb = 'hoge2'; // クラスの実行で単純に戻り値を返す return $bbb; } } --- MySmarty.class.php --- require_once 'test1.class.php'; require_once 'test2.class.php'; class MySmarty extends Smarty { function MySmarty() { //ここでclassTEST1,2の戻り値を利用しif文で分岐をしたい if ($aaa == 'hoge1') { $ccc = 'あああ'; } elee { $ccc = 'いいい'; } if ($bbb == 'hoge2') { $ddd = 'ううう'; } elee { $ddd = 'えええ'; } $this->assign('aaa', $aaa); $this->assign('bbb', $bbb); ・・・ } } このような使い方はできないものでしょうか?クラスに触れてまだ間も無く理解も深めれて いない状態で参考サイトなどを調べてみたのですがこのような使い方を書いている説明は みつかりませんでした。 思いつく方法としてはMySmartyに継承すればいいようなのですが継承は1つまでと 制限があるようでそれもできない状態です。 単純に1つのクラスにまとめて書けば済むような気もあるのですが他にも別のクラスの 戻り値を利用して分岐等をさせたく思っているのですがこの場合どうすればいいのでしょうか? もし不可能な場合(可能だけど方法的に良くない場合)の別の方法としてアドバイスを 頂けますと幸いです!宜しくお願いします!

    • 締切済み
    • PHP
  • 現在のクラスを生成したクラスに渡したい

    親クラスで生成した子クラス(ダイアログ)から親クラス(ダイアログ)の関数などを使えるようにしたいと思っております。 ちなみに継承クラスで親クラスの関数を使うのではなく、親クラスそのもの(ダイアログ表示)を子クラスから変更できるようにしたいです。 (簡単になりますが…)プログラムの構成は以下のようになっており、thisポインタを渡すか所でエラーが起こってしまいます。 ------------------------------------------------ class AAA { BBB *b; void classBBB{ b = new BBB(this); // こういうことがしたいが、できない void fun( int a ); // ダイアログの表示が変更する(予定) }; class BBB { AAA *a; BBB(AAA *pDlg){ a==pDlg; } void fun(){ int b; a->fun(b); } // 親クラスの関数を呼び出したい }; ------------------------------------------------ ただし、class Aとclass Bを生成する上位階層のプログラム構築をすることはなしとします。 ------------------------------------------------ こんな感じ AAA *a = new AAA(); BBB *b = new BBB(a); ------------------------------------------------ どうしてもclass AAAからclass BBB呼び出したいと思ってます。 何か良い解決法があれば、教えていただきたいです。 宜しくお願い致します。

  • クラスの宣言について

    Javaの初心者です。 webを探してもも良いサンプルが見つからなかったので、 詳しい方いらっしゃいましたらご教授ください。 以下、私の疑問です **************************** class AAA{ BBB bbb; void func(){ bbb = new BBB(); // コメント1 bbb.i = 10; // コメント2 } } class BBB{ int i; } **************************** お粗末なサンプルで申し訳ありません。 私の認識では、クラスAAAのfuncメソッドでコメント1の行の処理は 必須と思っていますが正しいでしょうか? それともコメント1の行はなくても、コメント2の行の処理は実行 できるのでしょうか? この「new」の必要性と理由が分からずにパニックになってます。 どなたかよろしくお願い致します。

  • C#でクラス継承について

    下記のようなコードは、可能なのでしょうか? // クラス定義 abstract class Base { int a; Public int A { get{ return a; } } } class Sub1 : Base { int b; public int B { set { b = value; } } }; class Sub2 : Base { // 中略 } static class Program { [STAThread] static void Main(string [] args) { Base aaa = new Sub1(); Base bbb = new Sub2(); func(aaa); // ここでCS1502, CS1503 func(bbb); // ここでCS1502, CS1503 } void func(Sub1 _aaa) { // 中略 } void func(Sub2 _bbb) { // 中略 } } コメントに書いたとおり、CS1502(引数が合わない)が出ます。 func((Sub1)aaa); の様にキャストしないと、動作させることは難しいでしょうか? ※ 実際のコードでは、func(aaa), func(bbb)の呼び出し部分をループでまわしたいと考えています。

  • classのdelete

    C++についてです。 class aaa; class bbb; とあったとします。 class aaaは、内部にclass bbb型の配列を 持っているとすると、aaaをdeleteする場合には aaaのデストラクタがcallされると思うのですが bbbのデストラクタは自動でcallされるのでしょうか (class bbbは、明示的にdeleteしないといけないのでしょうか?) 宜しく御願い致します。

  • 値のコピーについて

    お世話様です。 unsigned long aaa(32bit)にunsigned char bbb[4](8bit*4)を コピーする場合に、(1)と(2)で結果が違うのはなぜでしょうか? よろしくご教授お願いいたします。 (1)memcpy(&aaa bbb, 4); (2) { aaa = 0; unsigned long ccc = 0; ccc = static_cast<unsigned long>bbb[0]; aaa |= ((ccc << 24) & 0xFF000000); ccc = static_cast<unsigned long>bbb[1]; aaa |= ((ccc << 16) & 0x00FF0000); ccc = static_cast<unsigned long>bbb[2]; aaa |= ((ccc << 8) & 0x0000FF00); ccc = static_cast<unsigned long>bbb[3]; aaa |= ((ccc << 0) & 0x000000FF); } 【環境】CPU:Pentimum4 OS:WindowsXP コンパイラ:VC++8.0

  • c++のグローバル変数

    お世話になります c++のグローバル変数の使い方を教えていただけないでしょうか Visual Studio 2008を使用しております ------------abc.cpp------------- int AAA; BBB(){ AAA = 1; } abc::CCC(){ AAA = 2; } コンパイル(ビルド)ではエラーは出ないのですが、 BBBをコールした時は変数AAAに値をセットできるのですが、 abc::CCCをコールした時、AAAに値がセットできません、 ウォッチ等も「エラー:識別子'AAA'はスコープ外です」 となってしまいます。 補足 BBBはリンクしているライブラリ(修正不可)からコールされる為、 クラスに組み込む事が出来ません。

  • Excel 条件に一致したセルの隣のセルを返す

    エクセル初心者です。どうかご指導ください。 シート1の処理1・処理2・処理3に、シート2で一致したコードの隣の値を返したいのですが可能でしょうか? シート1                 シート2 コード 処理1 処理2 処理3   コード  処理名  1   AAA               1   AAA  2   BBB AAA           2   BBB  3   BBB               3   BBB  4   CCC AAA           2   AAA  5                      4   CCC                         4   AAA

  • 【ACCESS】重複チェック方法について

    下記のように、複数フィールドがあり、 フィールド1,2,3が全て同じレコードを抽出したいのですが 抽出する方法があれば、教えてください。 フィールド1 フィールド2 フィールド3 ・・・・ ――――――+――――――――+――――――――+――――― 12345 AAA aaa 12345 BBB aaa 12378 AAA aaa 12378 AAA bbb 23456 CCC bbb 23456 CCC bbb  ―>抽出したい!! 23456 CCC ccc

専門家に質問してみよう