![](/img/trans.png)
[英]How can you declare a class field that can be an object of one of a superclass's subclasses
[英]How can you declare that all subclasses of an abstract class will implement main?
我有一个名为Trader
的抽象类,它就像一个带有服务器的客户端(StockMarket),我想在Trader类中声明从它继承的所有类都需要实现一个主入口点,以便它们可以运行。
问题是,如果我写:
public static abstract void main(String[] args) throws Exception;
它给出了一个错误,即只允许使用可见性修饰符。 但是如果我删除静态修饰符,那么它就不能作为允许它运行的主入口点。
那么如何声明抽象类的所有子类必须实现一个main方法呢?
你不能。
我要做的是在Trader中声明一个抽象的非静态方法:
public abstract void run(String[] args) throws Exception;
然后声明一个单独的主类,它将实例化一个实例,并调用run方法:
class RunTrader {
private static final String DEFAULT_CLASS = "...";
public static void main(String[] args) {
try {
String className = System.getProperty("main-trader-class", DEFAULT_CLASS);
Class<Trader> traderClass = (Class<Trader>)Class.forName(className);
Trader trader = traderClass.newInstance();
trader.run(args);
} catch (Exception e) {
// handle the exception
}
}
}
静态方法不能是抽象的。
由于抽象方法需要在派生类中定义,因此它不能是静态的。 删除静态并尝试。
static
方法不支持多态,因此不能将其声明为abstract
。 但你可以使用@MauricePerry提出的抽象方法声明一个抽象类。 我会想出如何获得Main课程?
您可以从系统属性sun.java.command
提取Main类名。
这是我可以使用的实现:
public abstract class Trader {
protected abstract void run(String... args);
public static void main(String[] args) throws Exception {
runAs(getMainClass(args)).run(args);
}
private static Trader runAs(Class<?> mainClass)
throws IllegalAccessException, InstantiationException {
checking(!Modifier.isAbstract(mainClass.getModifiers())
, () -> "abstract class can't be run: " + mainClass);
checking(Trader.class.isAssignableFrom(mainClass)
, () -> "class is not a " + Trader.class
+ " can't be run: " + mainClass);
return Trader.class.cast(mainClass.newInstance());
}
private static void checking(boolean condition, Supplier<String> message) {
if (!condition) {
throw new IllegalArgumentException(message.get());
}
}
private static Class<?> getMainClass(String... args)
throws ClassNotFoundException {
String command = commandWithoutArgs(args);
String[] classes = command.split("\\s+");
return Class.forName(classes[ classes.length - 1]);
}
private static String commandWithoutArgs(String[] args) {
String command = System.getProperty("sun.java.command");
return command.substring(0, command.length() - argsLength(args)).trim();
}
private static int argsLength(String[] args) {
if (args.length == 0) {
return 0;
}
return Stream.of(args).collect(Collectors.joining(" ")).length() + 1;
}
}
public class Application extends Trader {
@Override
protected void run(String... args) {
System.out.println("Application");
}
}
运行Application
使用命令java Application
或在IDE运行它。
让我们从意义开始
public static void main (String[] args)...
静态的
意味着此方法确实需要类的实例(包含此方法)。 Java虚拟机(JVM)将此声明为程序入口点的要求,原因是该类可能具有多个构造函数或没有默认构造函数,并且JVM无法知道如何创建类的对象。
上市
允许该方法可以在包外部访问(显然是类),因此JVM可以自由地调用此方法。
主要
是JVM在类中查找的方法的名称,因为可能有多个公共静态方法。
空虚
没有回报。 这是JVM作为入口点查找的签名的一部分。
现在让我们根据这些信息回答你的问题。 多态性与OOP继承和接口实现概念相关,与静态方法无关。
因此,您唯一的选择是选择1'public static void main'方法作为基于'args'的入口点,调用其他公共静态方法。 但是,其他方法不需要具有相同的签名。
要运行程序JVM,请找到main方法,如public static void main(String [] args)abstract不与main方法一起使用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.