6

In writing a BookStoreApplication which uses Book, Tape, and CD classes to create objects. Although unfinished, the application class should create new BookStoreItems, which are Book, Tape, and CD. They inherit from the BookStoreItems class. In this application class I keep getting the error:

error: non-static method printMenu() cannot be referenced from a static context
error: non-static method getUserChoice() cannot be referenced from a static context
error: non-static variable input cannot be referenced from a static context

I've changed it to be static and then not to be static, yet I continue to get this error...

import java.util.Scanner;

public class BookStoreApp2 {

    //constants for options
    static final int ADD_BOOK = 0;
    static final int ADD_TAPE = 1;
    static final int ADD_CD = 2;
    static final int QUIT = -1;

    Scanner input = new Scanner (System.in);

    public static void main(String[] args) {


        BookStoreItem[] item;//declaring array

        item = new BookStoreItem[10];//initializing array

        int itemType = -1;

        printMenu();
        getUserChoice();

        for (int i = 0; i < item.length; i++){
            System.out.print("\n" + i + "\tEnter 0 for Book, 1 for Tape, 2 for CD: ");
            itemType = input.nextInt();

            switch (itemType) {
                case 0:
                    item[i] = new Book();
                    break;
                case 1:
                    item[i] = new Tape();
                    break;
                case 2:
                    item[i] = new CD();
                    break;
                default: 
                    System.out.println("\nInvalid choice.");
            }//end of switch statement

        }//end of for loop

        for (int i = 0; i < item.length; i++) {
            System.out.println("\nAnimal #" + i + ": ");

            System.out.println("\n\tTitle: " + item[i].getTitle()); //polymorphic because they can operate on separate objects
            System.out.println("\n\tAuthor: " + item[i].getAuthor());
        }//end of for


    }//end of main method


//PRINT MENU----------------------------------------------------------  
    public void printMenu(){
        System.out.println("\nPress:");
        System.out.println("\t" + ADD_BOOK + "\tTo add a book to the book store.\n");
        System.out.println("\t" + ADD_TAPE + "\tTo add a tape to the book store.\n");
        System.out.println("\t" + ADD_CD + "\tTo add a CD to the book store.\n");
        System.out.println("\t" + QUIT + "\tTo exit\n");
    }
//---------------------------------------------------------------------
//GET USER CHOICE------------------------------------------------------ 
     public int getUserChoice() {
        int choice;     
        System.out.print("Please enter your choice: ");
        choice = input.nextInt();

        return choice;
    }//end of getUserChoice
//----------------------------------------------------------------------

}//end class
user1368970
  • 555
  • 4
  • 10
  • 19

4 Answers4

18

You need to make both your method - printMenu() and getUserChoice() static, as you are directly invoking them from your static main method, without creating an instance of the class, those methods are defined in. And you cannot invoke a non-static method without any reference to an instance of the class they are defined in.

Alternatively you can change the method invocation part to:

BookStoreApp2 bookStoreApp = new BookStoreApp2();
bookStoreApp.printMenu();
bookStoreApp.getUserChoice();
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Now I have the methods as: `public static void printMenu()` and `public static void getUserChoice()`. But, I'm getting two errors of the same non-static problem and it's about `input`. about: `itemType = input.nextInt()` and `choice = input.nextInt()` – user1368970 Feb 13 '13 at 20:23
  • Move your declaration - `Scanner input = new Scanner (System.in);` inside the main method, and also in `getUserChoice()` method. – Rohit Jain Feb 13 '13 at 20:25
  • cannot find symbol input – user1368970 Feb 13 '13 at 20:26
  • 1
    @user1368970. Yeah sorry. See my edited comment. You need to add that to your `userChoice` method also. – Rohit Jain Feb 13 '13 at 20:26
  • @user1368970. And one more thing. Whenever you use `input.nextInt()`, add a blank `input.next();` line just after that, on the next line. – Rohit Jain Feb 13 '13 at 20:28
  • Ok Thank you. That worked. :) So now, whenever I need the scanner, I include it in the method I'm going to use it in? – user1368970 Feb 13 '13 at 20:29
  • @user1368970. Yes. Exactly. For now, just do that. – Rohit Jain Feb 13 '13 at 20:30
  • I get a null pointer exception when I do this though (by calling the method with an object)...What do you think the problem is? Let me know if you need any code. Thanks! (Been stuck on this for 3 and a half hours now!) – Ruchir Baronia Dec 10 '15 at 05:51
  • @RuchirBaronia Can you post your code? It's difficult to solve it otherwise. – Rohit Jain Dec 10 '15 at 08:03
  • Or just new BookStoreApp2().printMenu(); – john k Feb 26 '18 at 23:17
  • great answer @RohitJain it completely solved a lot of my problems in my app.thank you – Aishik kirtaniya Nov 30 '18 at 07:39
5

Merely for the purposes of making your program work, take the contents of your main() method and put them in a constructor:

public BookStoreApp2()
{
   // Put contents of main method here
}

Then, in your main() method. Do this:

public void main( String[] args )
{
  new BookStoreApp2();
}
mightyrick
  • 910
  • 4
  • 6
2

You can either

1) Declare printMenu(), getUserchoice() and input as static

OR

2) If you want to design it better, move the logic from your main into a separate instance method. And then from the main create a new instance of your class and call your instance method(s)

juherr
  • 5,640
  • 1
  • 21
  • 63
Rohit
  • 583
  • 6
  • 9
  • And use the main method just for calling the other methods to use them when needed? – user1368970 Feb 13 '13 at 20:31
  • 1
    The main method is basically an entry point into your application (from either command line using java classname or from an IDE.In you main method you basically initialize your objects and invoke methods.So to answer your question yes. – Rohit Feb 13 '13 at 20:45
1

You should place Scanner input = new Scanner (System.in); into the main method rather than creating the input object outside.

jerryg311
  • 98
  • 11