2009-03-03 18 views
2

私は抽象スーパークラスと様々なサブクラスを持っています。各サブクラスには静的に使用したい値が含まれていますが、抽象静的メソッドを作成することはできません。インスタンスを作成せずに動的に値を取得したいです。私は何をしますか?インスタンス化せずにサブクラスからデータを取得

もう1つの質問があります:サブクラスをどのようにループするのですか?それは可能ですか?

クラス名(Subclass.class)を値にマッピングしてnewInstanceを使用しようとしましたが、メソッドを使用して値を取得できましたが、これは機能しません。

どこで私のアプローチが間違っていますか?

+0

回答ありがとうございます。 値をインスタンスではなくクラスに関連付けることができます。 JavaScriptのような他の言語では、オブジェクトではなくクラスを参照するだけなので簡単です。残念ながら、クラス名は単独では格納できません。 1対1の関係 –

答えて

0

サブクラスの種類を表す2番目のクラスを作成することで、そのサブクラスが機能する可能性があります。

たとえば、各サブクラス(そのサブクラスのインスタンスを作成するクラス)のファクトリクラスを作成します。各工場クラスのインスタンスが1つだけ必要です。

各ファクトリクラスは、記述したサブクラス固有のデータを知る責任があります。その後、固定された一連のファクトリクラスをループするだけです。

+0

私はenum工場を使用しました。 –

1

他の方法はどうですか?どこかに静的にアクセス可能なデータを置いて、そこからサブクラスを取得させますか?

もちろん、この可能性はデータの性質に依存しますが、この種の障壁に当たったときは、しばしば前提を取り戻して再検証することに役立ちます。

- MarkusQ

+0

この方法ではカプセル化が失われますが、これはおそらくこの場合に行く方法だと思います。 –

0

あなたは、あなたがスーパークラスにデータを置くことができるサブクラスの固定セットを持っている場合。サブクラスを追加することができれば、それらをすべてリストする方法はありません。あなたは、スーパークラスが静的な初期化子からの存在を知ってもらうためにサブクラスを得るかもしれません(またはエージェントを使用してください)。

一般に、スーパークラスはそのサブクラスを認識すべきではありません。しかし、あなたのスーパークラスをスーパータイプとあなたのサブクラスを担当する他のクラスに考える(あるいはより良いリファクタリングをしたい)かもしれません。

0

あなたのスーパークラスを拡張するものを見つけるには、パッケージとクラスラをスキャンする必要があります - 残念ながら、これはReflection APIでは実行できませんが、URL(ファイルシステムクラス、jarファイルなど) 。この場合、注釈の使用がおそらく良いでしょう。そして、多くのオープンソース製品がこのメソッドを使用しています(Hibernateなど)。

その後、あなたは他のオプションは抽象クラスでレジストリマップを置くことであるあなたがmethod.invoke(MyObject.class, arguments)

ように呼び出すことができるはずそれぞれの静的メソッド(一貫性のある命名または注釈付きのいずれか)を持つことができます - あなたの場合それを強制する必要がある場合、抽象コンストラクタは静的な値を取ります(または、計算が必要な場合はサブクラスを格納します)。すべてのサブクラスを制御している場合は、レジストリに追加する静的ブロックがあることを確認してください。

+0

正しくリコールすれば、リフレクションAPIを使用してパッケージをスキャンすることはできません。 – McDowell

+0

ありがとう - 私はそれを忘れていた.. – Stephen

1

静的メンバー/メソッドはリフレクションで参照できますが、クラスのすべてのサブクラスを自動的に検索する方法はありません。

ServiceLoaderサービスや他のプラグインフレームワークなど、他のメカニズムを使用してサブクラス/インスタンスファクトリ/メタデータクラスを提供することを検討してください。

1

おそらくenumを探していますか?

public enum Planet 
{ 
    MERCURY (2.4397e6), 
    VENUS (6.0518e6), 
    EARTH (6.37814e6); 

    private final double radius; 

    Planet(double radius) 
    { 
    this.radius = radius; 
    } 

    public double radius() 
    { 
    return radius; 
    } 
} 

あなたはenumインスタンスを自分で作成する必要はありません。列挙型は値を持つことができます。この例ではradius()です。ビヘイビアを追加して、抽象メソッドを定義することで、通常のクラスのように動作させることができます。

あなたはこのような列挙型をループ、できる
public enum Planet 
{ 
    ... 
    abstract double weightOnSurface(double weight); 
    ... 
} 

:だから彼らは、すべての基準を満たすために

for (Planet p : Planet.values()) 
{ 
    System.out.println(p.radius()); 
} 

に見えます。

0

マッピングのサブクラス...あなたはリフレクションで行うことができますが、それは楽しいことではありません。クラスにはコンストラクタは、コンストラクタには、引数に

最後の1を取りません

  • 公開されて
  • 公開されて

    • :ない限り

      のnewInstance()(そうは)動作しません。他の2人は、あなたが何をしているのか(私が気にしてからしばらくしていたと思う)に依存しています。コンストラクタークラスを使う方が良いです。

      あなたはあなたが何をやっているのかの短いコード例を挙げることができますか?それに基づいて私(そして他の人)があなたにもっと良い答えを与えることができるかもしれません。マッピングサブクラスのことを行う必要がある場合、私はそれを行うコードを掘り下げることができます...

    関連する問題