如何声明抽象类的所有子类都将实现 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
}
}
}

让我们从

public static void main (String[] args)...

静态的

表示此方法确实需要类的实例(包含此方法)。Java 虚拟机 (JVM) 将此声明为程序入口点的要求,原因是该类可能有多个构造函数或没有默认构造函数,并且 JVM 无法知道如何创建该类的对象。

公共

允许该方法在包(显然和类)之外可访问,因此 JVM 可以自由调用此方法。

主要

是 JVM 在类中查找的方法的名称,因为可能有多个公共静态方法。

无效

不返回任何内容。这是 JVM 查找作为入口点的签名部分。

现在让我们根据这些信息回答您的问题。多态性与 OOP 的继承和接口实现概念相关,与静态方法无关。

所以你唯一的选择就是根据"args"选择 1 个"公共静态 void main"方法作为入口点,调用其他公共静态方法。但是,其他方法不需要具有相同的签名。

静态方法不能是抽象的。

  1. 静态成员数据对于所有对象和派生类都是相同的。
  2. 派生类不能重写静态成员。

由于抽象方法需要在派生类中定义,因此它不能是静态的。 删除静态并尝试。

>static方法不支持多态性,因此不能将其声明为abstract。 但是你可以用@MauricePerry提出的抽象方法来声明一个抽象类。我会想出如何获得主类?

您可以从系统属性中提取主类名sun.java.command

  1. 从命令中截断参数。
  2. 其次,截断 IDE 主类名(如果存在)。

这是我可以使用的实现:

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

使用命令java Application运行Application或在 IDE 中运行它。

要运行程序 JVM,请查找 main 方法,例如 公共静态空隙主(字符串[] 参数) 摘要不与主方法一起使用

相关内容

  • 没有找到相关文章

最新更新