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

时间:2017-05-22 06:21:43

标签: java inheritance subclass main abstract

我有一个名为Trader的抽象类,它就像一个带有服务器的客户端(StockMarket),我想在Trader类中声明从它继承的所有类都需要实现一个主入口点这样它们就可以运行了。

问题在于,如果我写:

public static abstract void main(String[] args) throws Exception;

它给出了一个错误,即只允许使用可见性修饰符。但是如果我删除静态修饰符,那么它就不能作为允许它运行的主入口点。

那么如何声明抽象类的所有子类必须实现一个main方法?

5 个答案:

答案 0 :(得分:1)

你不能。

我要做的是在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 :(得分:0)

静态方法不能是抽象的。

  1. 所有对象和派生类的静态成员数据相同。
  2. 静态成员无法被派生类覆盖。
  3. 由于抽象方法需要在派生类中定义,因此它不能是静态的。 删除静态并尝试。

答案 2 :(得分:0)

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

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

  1. 从命令中截断args。
  2. 第二步,截断IDE主类名称(如果存在)。
  3. 这是我可以使用的实现:

    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中运行它。

答案 3 :(得分:0)

让我们从

的含义开始
public static void main (String[] args)...
  

静态

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

  

公共

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

  

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

  

空隙

什么都不返回。这是JVM作为入口点查找的签名的一部分。

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

所以你唯一的选择是选择1&#39; public static void main&#39;方法作为基于&#39; args&#39;的入口点,调用其他公共静态方法。但是,其他方法不需要具有相同的签名。

答案 4 :(得分:-1)

运行程序JVM找到主要方法,如 public static void main(String [] args) abstract不与main方法一起使用