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 方法中实例化派生类。这似乎是不可能的。

我宁愿不必为每个派生类重复 main 方法,因为这感觉有点不合时宜。

有正确的方法吗?

4

6 回答 6

8

将 main 方法移到一个单独的类中。分离关注点
策略(名字说明一切)
启动器(将组件组装在一起并触发执行)

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

您不能实例化抽象类,但绝对可以从基类实例化派生类。所以只需从类定义中删除抽象

public class UselessStrategy

Strategy s = new UselessStrategy();
于 2010-06-07T09:33:16.587 回答
1

我会重新考虑这一点。

将您想要执行的代码放在其他地方,最好是非静态方法,然后调用它。 main()不应该这样使用。

我建议创建一个单独的 Strategy 类来代替 main。

于 2010-06-07T09:55:33.570 回答
0

从哪里调用主要方法?如果它需要参数,那么您可以根据这些参数决定一个具体的策略,实例化该策略类并调用execute它的方法。

于 2010-06-07T09:44:35.437 回答