5

クラスをインスタンス化し、メソッドを実行するメイン メソッドを定義する基本クラスを定義したいと考えています。ただし、いくつかの問題があります。基本クラスは次のとおりです。

public abstract class Strategy
{
    abstract void execute(SoccerRobot robot);

    public static void main(String args)
    {
        Strategy s = new /*Not sure what to put here*/();
        s.execute(new SoccerRobot())
    }
}

派生クラスの例を次に示します。

public class UselessStrategy
{
    void execute(SoccerRobot robot)
    {
        System.out.println("I'm useless")
    }
}

これは、メイン アプリケーションとして使用するときにメイン メソッドで呼び出す必要がある単純な実行メソッドを定義します。ただし、そのためには、基本クラスのメイン メソッド内から派生クラスをインスタンス化する必要があります。これは不可能のようです。

派生クラスごとに main メソッドを繰り返す必要はありません。

これを行う正しい方法はありますか?

4

6 に答える 6

8

メイン メソッドを別のクラスに移動します。個別の懸念
戦略 (名前がすべてを物語っています)
ランチャー (コンポーネントを組み立てて実行をトリガーする)

public class Launcher
{
    public static void main(String args)
    {
       Strategy s = new UselessStrategy();
          //OR Strategy s = CreateInstance(args[0]) ;
          //OR equiv mechanism for Dependency Injection if you don't want to hardcode the derived strategy to use.
        s.execute(new SoccerRobot())
    }
}
于 2010-06-07T09:41:42.587 に答える
3

「main」などの静的メソッドは継承されませんが、直接呼び出すことができます。回避策として、クラス名を main メソッドへの引数としてパラメータ化できます。

public static void main(String args) throws Exception
{
  String className = (args.length > 0) ? args[0] : 'UselessStrategy';
  Strategy s = (Strategy) Class.forName(className).newInstance();
  s.execute(new SoccerRobot())
}

不可能な場合Class.forNameは、Andreas_D のコメントに従って、クラス名のマッピングを維持することでルックアップ テーブルを提供できます。

private static Map<String, Class<? extends Strategy>> STRATEGY_NAME =
    new HashMap<String, Class<? extends Strategy>>();

static {
    STRATEGY_NAME.put("Useless", UselessStrategy.class);
    STRATEGY_NAME.put("Better", BetterStrategy.class);
}

public static void main(String args[]) throws Exception {
    String className = (args.length > 0) ? args[0] : null;
    Class<? extends Strategy> klass = STRATEGY_NAME.get(className);
    if (klass == null) klass = UselessStrategy.class;
    Strategy s = klass.newInstance();
    s.execute();
}

必要に応じて、リフレクションを使用するなど、マッピングを維持するための自動化された方法を考案できます。

于 2010-06-07T09:42:24.847 に答える
2

サブクラスの静的ブロックでクラスを定義できます。

public abstract class Strategy
{
    protected static Class<? extends Strategy> instanceClass;

    abstract void execute(SoccerRobot robot);

    public static void main(String args)
    {
        Strategy s = instanceClass.newInstance()
        s.execute(new SoccerRobot())
    }
}

その後

public class UselessStrategy extends Strategy
{
    static {
        instanceClass = UselessStrategy.class;
    }

    void execute(SoccerRobot robot)
    {
        System.out.println("I'm useless")
    }
}
于 2014-09-05T00:37:02.483 に答える
1

私はこれを再考します。

実行したいコードを別の場所、できれば非静的メソッドに置き、それを呼び出します。 main()このように使用しないでください。

メインの代わりに別の Strategy クラスを作成することをお勧めします。

于 2010-06-07T09:55:33.570 に答える
1

抽象クラスをインスタンス化することはできませんが、基本クラスから派生クラスをインスタンス化することはできます。したがって、クラス定義から抽象を削除するだけです

public class UselessStrategy

そして、やります

Strategy s = new UselessStrategy();
于 2010-06-07T09:33:16.587 に答える
0

メインメソッドはどこから呼び出されますか? 引数を取る場合、それらの引数に基づいて具体的な戦略を決定し、その戦略クラスをインスタンス化し、そのexecuteメソッドを呼び出すことができます。

于 2010-06-07T09:44:35.437 に答える