继承main方法

时间:2010-06-07 09:28:17

标签: java inheritance main-method

我想定义一个基类,它定义一个实例化类的main方法,并运行一个方法。但是有几个问题。这是基类:

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")
    }
}

它定义了一个简单的execute方法,在用作主应用程序时应该在main方法中调用。但是,为了做到这一点,我需要在基类的main方法中实例化派生类。这似乎是不可能的。

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

有没有正确的方法呢?

6 个答案:

答案 0 :(得分:7)

将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())
    }
}

答案 1 :(得分: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();
}

如果需要,可以设计用于维护映射的自动方法,例如使用反射。

答案 2 :(得分: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")
    }
}

答案 3 :(得分:1)

您无法实例化抽象类,但您肯定可以从基类中实例化派生类。所以只需从类定义中删除摘要

public class UselessStrategy

并做

Strategy s = new UselessStrategy();

答案 4 :(得分:1)

我想重新考虑一下。

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

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

答案 5 :(得分:0)

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