如何从代码中删除静态方法(以及如何替换它们)

How to remove static methods from a code (and how to replace them)

我对编程很陌生,Java 只是想让你知道...

我正在研究一个 code/program 框架(学校作业),它具有以下描述实施和测试命令控制程序的框架,它旨在用于跟踪dogs at a dog day,程序在第一阶段必须接受的命令如下: -注册新狗 -增加年龄 -列出狗 -删除狗 -退出

这些命令中唯一应该正确工作的命令是 exit,它应该打印一条程序已终止的消息,然后终止程序。这必须通过关闭命令行来完成,而不是通过不能使用的 System.exit 来完成。 其他命令应该只打印一个简短的文本,告诉指定了哪个命令。此文本必须包含上面的完整命令名称,以便测试程序可以识别它们。一个技巧是也接受其他更短的命令,以便您自己的测试变得更容易。"

其中一个非功能性要求是除主字符串外不得使用静态方法或变量。

因此我的问题是;如何从我的程序框架中删除静态方法?我真的很难理解这个!

import java.util.Scanner;

public class ProgramSkeleton {

    static Scanner input = new Scanner(System.in);

    public static void initialize() {
        System.out.println("Welcome to the dog register!");
        System.out.println("Write 0 to register new dog");
        System.out.println("Write 1 to increase age");
        System.out.println("Write 2 to list dogs");
        System.out.println("Write 3 to remove dog");
        System.out.println("Write 4 to exit");
    }

    public static void runCommandLoop() {
        boolean done;
        do {
            String command = readCommand();
            done = handleCommand(command);
        } while (!done);
    }

    public static String readCommand() {
        System.out.print("> ");
        String command = input.nextLine();
        return command;
    }

    private static boolean handleCommand(String command) {
        switch (command) {
        case "0":
        case "register new dog":
            System.out.println("You have chosen register new dog.");
            return true;
        case "1":
        case "increase age":
            System.out.println("You have chosen increase age.");
            return true;
        case "2":
        case "list dogs":
            System.out.println("You have chosen list dogs.");
            return true;
        case "3":
        case "remove dog":
            System.out.println("You have chosen remove dog.");
            return true;
        case "4":
            break;
        default:
            System.out.println("unknown command");
            return false;
        }
        return false;
    }

    public static void closeDown() {
        System.out.println("Goodbye!");
    }

    public static void main(String[] args) {
        initialize();
        runCommandLoop();
        closeDown();
    }

}

您被迫不执行此作业中的 static 方法的原因是迫使您使用更面向对象的方法。

如何创建一个 Command 抽象基础 class(或接口,取决于你到目前为止在课程中所做的),然后为每个特定的 class 创建不同的你有命令,所以 RegisterDogCommandListDogsCommandsUpdateAgeCommandRemoveDogCommand,它们都扩展了 Command

每个 Command 都可以实现一个 execute() 方法(可以是 Command 中的一个抽象方法,然后被每个具体 class 覆盖),它可以做任何它需要做的事情.

在您的 main() 函数中,在您拥有 switch-case 的地方,您只需创建正确的 Command 对象,然后调用 execute()

这也称为 command pattern

如其他答案所示,class 与您的 main() 方法也可以实例化,然后可以在 ProgramSkeleton 的实例上调用您拥有的函数(因此不本身需要 static)。不确定您的作业的 objective 是什么(是仅删除 static 还是以面向对象的方式实施命令)。

好吧......你需要一个对象来调用它的方法,如果它们不是static

话虽如此,只需删除 class 中的任何 static 关键字,main 方法除外。然后把这个main方法改成:

public static void main(String[] args) {
    ProgramSkeleton program = new ProgramSkeleton();
    program.initialize();
    program.runCommandLoop();
    program.closeDown();
}

而不是调用

    initialize();
    runCommandLoop();
    closeDown();

创建程序框架的新实例...

    ProgramSkeleton skeleton = new ProgramSkeleton();
    skeleton.initialize();
    skeleton.runCommandLoop();
    skeleton.closeDown();

这将允许您从所有其他方法签名中删除 static 关键字,因为它们现在与 ProgramSkeleton 的一个实例关联 class。

首先从你的方法中删除"static"关键字,然后在你主要创建一个class ProgramSkeleton的实例,然后使用这个对象的方法:

//remove static
public void initialize() {
    System.out.println("Welcome to the dog register!");

    System.out.println("Write 0 to register new dog");
    System.out.println("Write 1 to increase age");
    System.out.println("Write 2 to list dogs");
    System.out.println("Write 3 to remove dog");
    System.out.println("Write 4 to exit");
}
...

//Create object in main
...
ProgramSkeleton programSkeleton = new ProgramSkeleton();
programSkeleton.initialize()

您的规范并未阻止您创建 class 的实例,因此我认为您不需要将变量和方法设为静态。 (除非您被特别要求在不创建实例的情况下调用 class 的方法)。

首先你盲目地从你所有的方法中删除static关键字(main方法除外),然后它会给出编译时错误说

Cannot make a static reference to the non-static method

没错,当您删除其他方法的所有 static 关键字时,它会变成非静态的,并且 Java 编译器不会让您从任何静态块或方法中调用它们,除非您创建一个对象并使用它引用调用这些方法。

然后在你的 main 方法中像这样更改代码

ProgramSkeleton programSkeleton = new ProgramSkeleton();
programSkeleton.initialize();
programSkeleton.runCommandLoop();
programSkeleton.closeDown();

静态方法就像 for-free 你可以自由调用(不需要对象),但对于非静态方法则不然。你可以在不使用引用的情况下从另一个非静态方法调用非静态方法,但你不能从静态块调用非静态方法,除非你按照我之前说的去做。

例子

public class RemoveStatic {

    static void test1() {
        test3();    //  error because we need to create an object and call test3() on its reference
    }

    void test2() {
        test3();    //  perfectly fine - We can call a non-static method inside another non-static method
    }

    void test3() {

    }

    public static void main(String[] args) {
        //  How to call a non-static method inside a static method
        RemoveStatic removeStatic = new RemoveStatic();
        //  removeStatic is the reference to the object
        removeStatic.test3();

        test1();    //  static methods dosen't need a refernce to be called
    }
}