リストする派生クラスをStringで表現するデータ形式の管理方法

このQ&Aのポイント
  • Stringで表現する独自のデータ形式に対応するために、abstract class DataType を利用する。
  • ManagerOfDataTypeクラスのメソッドを使用して、サポートされているすべてのデータ形式を取得できる。
  • データ形式の派生クラスをすべて取得するための最適な方法は、インスタンス生成時にクラス名を登録することで実現できる。
回答を見る
  • ベストアンサー

派生クラスをリストする

Stringであらわせる独自のデータ形式がいくつかあり、次のようにして、 abstract class DataType{ //このファイル形式かどうかを判定する abstract boolean isThisDataType(String s); } class DataTypeA extends DataType{ boolean isThisDataType(String s){...} } class DataTypeB extends DataType{ boolean isThisDataType(String s){...} } class ManagerOfDataType{ DataType[] getAllSupportedDataTypes(){...} //サポートしているすべてのデータ形式を取得 DataType FindBestDataType(String s){ for(i=0;i<getAllSupportedDateTypes().length();i++){ if(getAllSupportedDataTypes()[i].isThisDataType(s)){ return getAllSupportedDataTypes()[i]; } } } } のようにして、どのデータ形式でも対応できるようにしたいと思っているのですが、わからないのは、「サポートしているすべてのデータ形式を取得」、すなわち、DataTypeの派生クラスをすべて取得するところです。 DataTypeA,BのコンストラクタでstaticなListに自分のクラス名を登録していくなどの方法も思いついたのですが、それでは、DataTypeA,Bのインスタンスを生成したときしか登録が実行されませんよね?宣言すると同時に、登録が実行されるような方法はありますでしょうか? もっとスマートなデザインパターンがあるぞ、という話でも、お教えくだされば幸いです。

  • Java
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

#1です。 >一つ考えたのは,パッケージを組んで,パッケージの下に属するすべてのクラスを リストアップするという方法なんですが・・・ そのように、限定をしていいのなら方法はあります。 私がよくやる方法で、プラグイン的な処理です。 概略は、 1.データ形式を表すクラスを、限定したディレクトリに入れておく。  [補足1]通常のクラスパスではないディレクトリにした方が、    扱いやすいし検索速度も上がるため。(経験上)  [補足2]ディレクトリには、クラスファイル単独ではなく、    パッケージを表すディレクトリ構造ごと格納すること。 2.そのディレクトリ階層から拡張子.classのファイルを対象として、   自作ClassLoaderでロードする。  [補足]通常のClassLoaderでは、クラスパスからしか読めないためカスタマイズ。 3.読んだClassオブジェクトが、DataTypeのサブクラスならリストへ追加。   [補足]「instanceof」で判断できる。

betagamma
質問者

お礼

お礼が非常に遅くなってしまい、大変申し訳ありません。 結局、単に自動的に読み込めた方がきれい、というだけの問題でどうしても必要な機能ではなかったため、実装せずに一つ一つクラスを追加する方法で解決させてしまいました。せっかくの回答を生かせずに申し訳ありません。 ただ、結果的に方法がある、と分かっただけでも幸いです。やはり、自作クラスローダを使わないと無理だったのですね....技術的にはいろんなところで使えそうです。勉強になりました。覚えておこうと思います。 回答ありがとうございました。

その他の回答 (1)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.1

やっぱり、ManagerOfDataTypeのコンストラクタで必要な登録をするコードを書くか、 定義ファイルなどを用意しておいて、それを読むしかないのでは? 何の指示もせず、ManagerOfDataTypeのインスタンスを生成しただけでリストを作るのは無理があると思いますけど。 DataTypeを継承したクラスがどこにあるか分からないし、 本当にリストに追加していいのかも判断できない。

betagamma
質問者

お礼

回答ありがとうございます。 >DataTypeを継承したクラスがどこにあるか分からないし、 本当にリストに追加していいのかも判断できない。 とりあえず、派生クラス名さえ集められれば、java.lang.ClassのgetSuperclassを使って、DataType型から派生しているかどうかは分かるんですが。内部クラスやメンバクラスをリストする関数はあるのに、派生クラスをリストする関数はないんです。 やはり無理なんでしょうかねぇ。一つ考えたのは,パッケージを組んで,パッケージの下に属するすべてのクラスをリストアップするという方法なんですが・・・これも、同じように、クラス名が分かっているときに、その所属がどのパッケージかを示す関数はあるんですが、逆の方法がわかりません。 ManagerOfDataTypeは、別にstaticでもいいんですが・・・

関連するQ&A

  • javaの配列とクラス

    abstract class abstract_class{ } class subclassA extends abstract_class{ int num = 1; } class subclassB extends abstract_class{ int num = 2; } class subclassC extends abstract_class{ int num = 3; } class Main{ public static void main(String args[]){ int sum = 0; abstract_class var[] = new abstract_class[3]; var[0] = new subclassA(); var[1] = new subclassB(); var[2] = new subclassC(); for(int i=0;i<3;i++) sum += var[i].num; System.out.println(sum); } } これをコンパイルすると Main.java:23: シンボルを見つけられません。 シンボル: 変数 num 場所 : abstract_class の クラス for(int i=0;i<3;i++) sum += var[i].num; ^ エラー 1 個 というエラーが出るのはなぜでしょうか? var[i]はみなsubclassA,subclassB,subclassCが代入されているのに、numはabstract_classの変数となっています。 よくわかりません。 よろしくお願いします。

    • ベストアンサー
    • Java
  • abstract クラスについて

    お世話になります。 abstract クラスについて質問させて下さい。 例えば、以下のような場合、 abstract class ErrorC { abstract boolean errorKind( ); public void logOut( ) { //ログを記録する処理を記述する } } class DbError extends ErrorC { boolean errorKind( ) { //DB エラーが起こった時の処理を記述する logOut( ); } } class IoError extends ErrorC { boolean errorKind( ) { //入出力エラーが起こった時の処理を記述する logOut( ); } } ・ErrorC クラスではエラーの種類に関わらず、ログを記録する処理を  記述する。 ・それ以外の個々のエラー毎の処理は各サブクラスに具体的な処理を  実装させる。 ということで、プログラミングの作業量が軽減される等の利点は理解できる のですが、それを実現するには、普通にクラスの継承を行えばいいような 気がするのです。 abstract クラスがどういうものなのか、ということは何となく理解できたのですが、 それを使用する利点が分かりません。 ご教授宜しくお願い致します。

    • ベストアンサー
    • Java
  • インターフェイス 抽象クラス

    PHP初心者です。 xampp1.7.0(最新)でアパッチなど一括ダウンロード クラスの概念は分かりましたが、インターフェイス、及び抽象クラスについて理解が追い付きません。 下記コードをご覧ください。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <? abstract class AbstractClass { abstract public function test1(); } class Impl1 extends AbstractClass { public function test1() { print "こんにちは\n"; } } class Impl2 extends AbstractClass { public function test1() { print "ありがとう.\n"; } public function hoge() { print "さようなら\n"; } } $i1 = new Impl1(); $i1->test1(); $i2 = new Impl2(); $i2->test1(); ?> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 抽象クラスが上にありますが、中身がないので継承し、そのクラスの中で処理させています。抽象クラスの必然性が理解できません。まあこのコード事態がものすごく短いので、その必然性がないと思うのですが、例えばもっと長いコードになったときなどは抽象クラスは絶対使った方がいいということになるのでしょうか。 さらに全て抽象クラスであればインターフェイスを利用できるようですが、インターフェイスのメリットにつき理解が追い付きません。 どなたかご教授お願いいたします。

    • ベストアンサー
    • PHP
  • パラメータのやりとり

    3つのクラスの中でHTML上から取得したパラメータをやり取りしたいと思っています。 1つ目のクラス(CLASS_1.java) public class CLASS_1 extends CLASS_0 { public void doMain(HttpServletRequest request,HttpServletResponse response){ try{ String[] str = makeItem(request); CLASS_2 class_2 = new CLASS_2(); class_2.setItem(str); private String[] makeItem(HttpServletRequest request){ String[] result = new String[3]; result[0] = request.getParameter("test1"); result[1] = request.getParameter("test2"); result[2] = request.getParameter("test3"); return result; 2つ目のクラス(CLASS_3.Java) public class CLASS_3{ public void setItem(String[] data){ } public boolean makeTEXT(){ return true; } public ByteArrayOutputStream getTEXT(){ return null; } } 3つ目のクラス(CLASS_2) public class CLASS_2 extends CLASS_3 { public boolean makeTEXT(){ return true; } } という3つのクラスを作成しました。 CLASS_1で取得したstrの中の値をCLASS_2で使用したいと考えています。 ただ羅列するだけでかまいませんので、わかるかたヒントや参考になりそうなHPなどありましたら よろしくお願いします。

  • スーパークラスの取得の仕方

    どなたかお知恵を貸してください。 現在抽象クラスを作って表示をさせる実験をしています。 ですが、下記ソースでは、取得したnameをが参照することができません。 どのようにすれば、たまの名前を出すことが出来るのでしょうか よろしくお願いいたします。 abstract class Mammals { /** 名前を表す */ String name; abstract public void introduceOneself(); public void setName(String name) { name = name; } } class Cat extends Mammals { public Cat() { super(); } public void introduceOneself() { System.out.println(name+"です。うにゃにゃ。"); } } class Main { public static void main (String[] args) { Cat tama = new Cat(); //コンストラクタ呼び出し Mammals neko = tama; //コンストラクタ呼び出し neko.setName("たま"); //自己紹介する tama.introduceOneself(); //自己紹介する } }

    • ベストアンサー
    • Java
  • 抽象クラスからオーバーライドについて

    EclipseでJavaを勉強始めました。 抽象クラスからオーバーライドするところで質問致します。 抽象クラスとして、「面積を計算する」というメソッドをもつDiagramクラスを定義しました。それを継承して、「四角形の面積を計算する」というメソッドをもつSquareクラスと、「三角形の面積を計算する」というメソッドをもつTriangleクラスを定義しました。 Squareクラス、Triangleクラスからインスタンスを生成して、四角形、三角形の面積をコンソールに表示させるという簡単なプログラムです。 このとき、main関数と3つのクラスの関係についてお尋ねします。 (1)iagram.java、Square.java、Triangle.javaそれぞれにクラス定義とmain関数を持たせるパターン public abstract class Diagram { // 面積計算定義(抽象メソッド) public static void main(String[] args) { } } public class Square extends Diagram{ //四角形の面積の計算定義 public static void main(String[] args) { //四角形の面積の計算と表示 } public class Triangle extends Diagram{ //三角形の面積の計算定義 public static void main(String[] args) { //三角形の面積の計算と表示 } (2)sample.javaというファイルにまとめ、その中にこの3つのクラス定義とmain関数を一つ持たせるパターン public class sample { public static void main(String[] args) { //四角形の面積の計算と表示 //三角形の面積の計算と表示 } } abstract class Diagram { // 面積計算(抽象メソッド)定義 } class Square extends Diagram{ //四角形の面積の計算定義 } class Trapezoid extends Diagram{ //三角形の面積の計算定義 } この二通りを考えて、どちらも実行できたのですが、どちらの方がJavaらしいプログラムと思われますでしょうか?

    • ベストアンサー
    • Java
  • 抽象クラス について

    obj.write();した時 class super1 の write()が呼ばれ その後 class HINA の write()が呼ばるのか? 直接 class HINA の write()が呼ばるのか? どう呼び出してるのか 教えてください abstract class super1 { abstract void write(); } class HINA extends super1{ void write() { System.out.println( "LOVE HINA" ); } } class test { public static void main( String args[] ) { super1 obj = new HINA(); obj.write(); } } }

  • 配列クラスのクラス名

    配列クラスのクラス名 配列クラスのクラス名を教えてください。 配列はクラスですよね。そこまでは分かります。 こんなコードを実行しましたが System.out.println((new int[0]).getClass()); System.out.println((new boolean[0]).getClass()); System.out.println((new String[0]).getClass()); System.out.println((new Integer[0]).getClass()); 親切にこのような結果を出力してくれます。 class [I class [Z class [Ljava.lang.String; class [Ljava.lang.Integer; 結果として配列が何というクラスなのかは分かりません。 (もしかして『[I』『[Z』『[L』という名前のクラスでしょうか?) 昔Javaのソースを読んだときに、配列クラスのファイルも 読んだことがあるような気がするのですが、 なんと言うクラスだったか忘れてしまいました。 パッケージ名+クラス名を教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java
  • List<T> クラスでデータを入れても同じになる

    Wireless_unit_sigクラスというのにデータを入れていきたいのですが、読み込んだファイルの中にデータが20000データぐらいあるため、Listジェネリッククラスというので宣言してみました。 List<Wireless_unit_sig^>^ Wireless_ID_str02 = gcnew List<Wireless_unit_sig^>(); この時に、 Wireless_ID_str02[i]->day_name = split[0]; Wireless_ID_str02[i]->month = split[1]; Wireless_ID_str02[i]->day = split[2]; Wireless_ID_str02[i]->time = split[3]; Wireless_ID_str02[i]->year = split[4]; Wireless_ID_str02[i]->cmd1 = split[5]; Wireless_ID_str02[i]->cmd2 = split[6]; Wireless_ID_str02[i]->ID = split[7]; Wireless_ID_str02[i]->sig1 = split[8]; Wireless_ID_str02[i]->sig2 = split[9]; Wireless_ID_str02[i]->batt_mount = split[10]; Wireless_ID_str02[i]->m_rssi = split[11]; Wireless_ID_str02[i]->s_rssi = split[12]; Wireless_ID_str02[i]->version = split[13]; このようにデータを入れていこうとしたのですが、エラーが出るのですが、データを収納していく方法というのはどのようにしていけばよいのでしょうか? 作成したクラスは次のようなものです。 どうぞ、教えて頂きますよう、お願い致します。 ref class Wireless_unit_sig { private: public: String^ day_name; String^ month; String^ day; String^ time; String^ year; String^ cmd1; String^ cmd2; String^ ID; String^ sig1; String^ sig2; String^ batt_mount; String^ m_rssi; String^ s_rssi; String^ version; String^ s_rssi_fixed; public: Wireless_unit_sig() { day_name = "test"; month = "test"; day = "test"; time = "test"; year = "test"; cmd1 = "test"; cmd2 = "test"; ID = "test"; sig1 = "test"; sig2 = "test"; batt_mount = "test"; m_rssi = "test"; s_rssi = "test"; version = "test"; s_rssi_fixed = "test"; } }; }

  • インタフェイス実装と抽象クラス継承を同時に使うには??

    私はjava初心者です、今練習問題で困っています。 1つのクラスに抽象クラスとインターフェイスを 実装することはできるのでしょうか? 例えば abstract class Car { private String gas; public void getGas(int gas) { this.gas = gas; } public abstract void enjin(); } interface Flying extends Pet { void show(); } 上のインタフェイスと抽象クラスを同時に下のクラスに継承、実装しよう とすると、どんな風にかけば良いのでしょうか class Zoon { public Zoon() { super(); } public void enjin() { System.out.println("どどどどど"); } public void show() { System.out.println("いいくるまだ"); } }

    • ベストアンサー
    • Java

専門家に質問してみよう