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

时间:2019-01-09 11:40:26

标签: java static-methods instance-methods

我对编程和Java还是很陌生,所以您知道...

我正在研究一个代码/程序框架(在学校分配),该框架具有以下描述,用于实现并测试命令控制程序的框架,它旨在用于跟踪狗的狗,程序在第一阶段必须接受的命令如下: -注册新狗 -增加年龄 清单狗 -删除狗 -退出

这些命令中唯一可以正常工作的命令是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();
    }

}

6 个答案:

答案 0 :(得分:3)

代替打电话

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

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

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

这将使您从所有其他方法签名中删除static关键字,因为它们现在已与ProgramSkeleton类的实例相关联。

答案 1 :(得分:2)

在此分配中被迫不执行static方法的原因是迫使您使用面向对象的方法。

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

每个Command可以实现一个execute()方法(可以是Command中的抽象方法,然后被每个具体的类覆盖),该方法可以完成所需的操作。

main()函数中,只要拥有switch-case,您就可以创建正确的Command对象,然后调用execute()

这也称为command pattern

如其他答案所示,还可以实例化具有main()方法的类,然后可以在ProgramSkeleton的实例上调用您拥有的函数(因此不必是{{1 }}本身)。不确定分配的目的是什么(只是删除static还是以面向对象的方式实现命令。)

答案 2 :(得分:0)

好吧……如果它们不是 static ,则需要一个 object 来在其上调用方法。

话虽如此,只需删除类中的任何static关键字,除了main方法。然后将此主要方法更改为:

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

答案 3 :(得分:0)

首先从您的方法中删除“ static”关键字,然后在您的main中创建一个类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()

答案 4 :(得分:0)

首先您从所有拥有的方法(主方法除外)中盲目删除static关键字,然后将给出编译时错误提示

  

无法静态引用非静态方法

是正确的,当您删除其他方法的所有static关键字时,它变为非静态,并且Java编译器不允许您从任何静态块或方法中调用它们,除非您创建对象并使用其引用来调用这些方法

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

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

静态方法就像免费一样,您可以自由调用(不需要对象),但对于非静态方法则不能。您可以在不使用引用的情况下从另一个非静态方法中调用非静态方法,但是除非您按照我之前所说的那样,否则不能从静态块中调用非静态方法。

示例

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
    }
}

答案 5 :(得分:-1)

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