繁体   English   中英

如何声明抽象类的所有子类都将实现main?

[英]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
        }
    }
}

静态方法不能是抽象的。

  1. 所有对象和派生类的静态成员数据都相同。
  2. 静态成员不能被派生类覆盖。

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

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

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

  1. 截断命令中的args。
  2. 第二,截断IDE 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM