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

Viewed 3229

I'm very new to programming and Java just so you know...

I'm working on a code/program skeleton (assignment in school) which has the following description implement and test a skeleton for a command-controlled program and it is intended to be used to keep track of the dogs at a dog day, and the commands that the program must accept at the first stage are as follows: -register new dog -increase age -list dogs -remove dog -exit

The only one of these commands that should work correctly is exit that should print a message that the program is terminated and then terminate the program. This must be done by closing the command line, and not by System.exit, which must not be used. The other commands should only print a short text that tells which command was specified. This text must contain the full command name as above so that the test program can identify them. One tip is to also accept other, shorter, commands so that your own testing becomes easier."

One of the non-functional requirements is that no static methods or variables may be used except on the main string.

My question is therefore; HOW can I remove the static methods from my program skeleton? I have a really hard time understanding this!

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 Answers

Instead of calling

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

create a new instance of your program skeleton...

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

This will let you remove the static keyword from all of the other method signatures, as they are now associated with an instance of the ProgramSkeleton class.

The reason you are being forced not to do static methods in this assignment is to force you into using a more object oriented approach.

What about creating a Command abstract base class (or interface, depending on what you did so far in your course), and then creating different classes for each specific command you have, so RegisterDogCommand, ListDogsCommands, UpdateAgeCommand, RemoveDogCommand, which all extend Command.

Each Command could implement an execute() method (could be an abstract method in Command then overridden by each concrete class) which does whatever it needs to do.

In your main() function, where you have your switch-case you just create the right Command object, and then call execute().

This is also known as the command pattern.

As indicated in other answers, the class with your main() method could also be instantiated and the functions you have could then be called on the instance of ProgramSkeleton (thus not needing to be static per se). Not sure what was the objective of your assignment (whether to just remove static or implement commands in an object oriented way).

Well ... You need an object to call methods on it, if they are not static.

Having said this, simply remove any static keyword in your class, except for the main method. Then change this main method to:

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

First of all remove "static" keyword from your methods, and then in you main create an instance of the class ProgramSkeleton, then use the methods of this object:

//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()

First you blindly remove static keywords from all the methods you have (except main method), then it will give compile time error saying

Cannot make a static reference to the non-static method

That's correct, when you removed all the static keyword for other methods it became non-static and Java compiler won't let you call them from any static block or method unless you create an object and use its reference to call those methods.

Then in your main method change the code like this

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

Static methods are like for-free you can call freely (no need of an object), but for non-static its not. You can call a non-static method from another non-static method without using a reference, but you can't call a non-static method from a static block unless you do what I said before.

Example

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

Your specification didn't stop you from creating an instance of your class, so I don't think you need to make the variables and methods static. (except you were specifically asked to call the methods of your class without creating an instance).

Related