我想定义一个基类,它定义一个实例化类的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方法,因为它感觉有点不合时宜。
有没有正确的方法呢?
答案 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
方法。