在抽象中有 main 方法 class

Having main method in an abstract class

我知道在抽象 class 中使用 main 方法是合法的,因为 Eclipse 允许我执行以下操作并且 运行 class 作为 java应用。但是这样做有意义吗?

现实世界中是否存在需要在抽象中使用 main 方法的场景class?

public abstract class Automobile
{
    public Boolean powerOn()
    {
        // generic implementation for powering on an automobile
        return true;
    }


    public void move()
    {
        // generic implementation for move
    }

    public void changeDirection(String newDir)
    {
        // generic implementation for changing direction
    }

    public abstract void accelerate(Integer changeInSpeed);
    public abstract Integer refuel(Integer inputFuel);

    public static void main(String[] args) 
    {
        System.out.println("I am a main method inside an abstract Automobile class");
    }
}

您可以创建另一个 class 的对象并通过组合使用其他 class 方法

class Test1 {

    int x = 10;

    public void display() {
        System.out.println("Hello! This is Test1 class");
    }
}

public abstract class Test {

    public static void main(String args[]) {
        Test1 t1 = new Test1();
        System.out.println("From abstract class main(): " + t1.x);
        t1.display();
    }
}

不,不是真的。尝试创建一个 class 层次结构,其中不同的 classes 共享相同的主要方法似乎没有用。看这个例子:

public abstract class A {

    public static void doStuff() {
        System.out.println("A");
    }

    public static void main(String[] args) {
        System.out.println("starting main in A");
        doStuff();
    }
}

class B extends A {
    public static void doStuff() {
        System.out.println("B");
    }
}

这会打印出来

c:\Users\ndh>java A
starting main in A
A

这是意料之中的,但很无聊,

c:\Users\ndh>java B
starting main in A   
A        

这不是你想要的。

隐藏静态方法调用不像实例方法的虚拟覆盖那样工作,您必须首先显式命名 class 以用作查找正确方法签名的起点(或者默认情况下您获取调用所在的 class)。问题是 main 方法不知道 subclasses(或者把它放在抽象 class 上有什么意义),所以没有好的方法来获取 subclass-特定信息进入superclass main方法。

我的偏好是尽量减少对 static 关键字的使用,将其保留用于常量(尽管自从枚举出现以来就没有那么多了)和没有依赖关系的无状态函数。取而代之的是面向对象的技术。对于静态方法,您必须具体。使用 OO 的想法是您可以避免具体化,让子 class 自己照顾自己。

你问的是需要 main 方法在 abstract class 中的场景,但我可以反过来问:有没有需要在非 abstract class?

中使用 main 方法

显然,应用程序入口点是否在 abstract class 内完全无关。重要的是:

  • 那个class一定是public
  • 它应该有一个对外界有用的名称,因为它将出现在非Java上下文中,即命令行、启动脚本或XML文件、文档等

就是说,如果您的应用程序包含一个 public abstract 基础 class 和一个简洁的名称(如 Automobile)和一些实现 classes不是 public and/or 难以记住的名称(如 AutomobileXF838EngineImpl),选择 class 作为应用程序入口点的基础是有道理的。

但这仅适用于相当小的应用程序,其中 classes 的数量很重要。对于较大的应用程序,您通常会有一个专用的 class 作为应用程序入口点托管 main 方法。甚至可能有多个启动 classes 用于不同的环境或框架。

所以这些开始 class 既不是 abstract 基础 class 也不是这种基础 class 的实现 class,而是完全不相关的到这样的 class 层次结构。由于它们不是类型层次结构的基础 classes,因此它们通常不是 abstract.