2015-02-03 2 views
0

저는 자바를 배우려고 애 쓰고 있습니다. 한 클래스에서 다른 클래스로 함수를 호출하는 방법을 이해하려고 시도하고 있습니다. 나는 아래에 게시 할 두 개의 수업을 가지고 있습니다. ToDo 클래스에서 H2db.addItems()를 호출 할 때 및 H2db 클래스에서 ToDo.menu()를 호출 할 때 "정적이 아닌 메서드를 정적 컨텍스트에서 참조 할 수 없습니다."가 나타납니다. 인터넷 검색은 인스턴스 (?)와 관련이 있다고 밝혔지만 그 의미가 확실하지 않습니다.정적 함수와 인스턴스가이 경우 어떻게 함께 작동합니까?

클래스 할일 :

package com.company; 


import java.io.*; 
import java.lang.reflect.Method; 
import java.sql.*; 
import java.util.ArrayList; 
import java.util.Scanner; 

public class ToDo { 
    //BufferedReader inputread = new BufferedReader(new InputStreamReader(System.in)); 
    Scanner inputread = new Scanner(System.in); 
    ArrayList<String> toDoList = new ArrayList<String>(); 


    public void menu() { 
     clearConsole(); 
     System.out.println("Welcome to the To-Do program."); 
     System.out.println(); 
     System.out.println(); 
     System.out.println("Please select an option from the following menu, using the number.:"); 
     System.out.println("1- View To-Do List"); 
     System.out.println("2- Add Item To List"); 
     System.out.println("3- Remove Item From List"); 
     System.out.println("4- Save List"); 
     System.out.println("5- Load List"); 

     int userinput = inputread.nextInt(); 

     switch (userinput) { 
      case 1: 
       clearConsole(); 
       displayList(true); 
       menu(); 
       break; 
      case 2: 
       clearConsole(); 
       H2db.addItems(); 
       break; 
      case 3: 
       clearConsole(); 
       deleteItem(); 
       break; 
      case 4: 
       clearConsole(); 
       try { 
        saveList(); 
       } 
       catch(IOException e){ 
        return; 
       }; 

      case 5: 
       clearConsole(); 
       try { 
        loadList(); 
       } 
       catch(IOException e){ 
        return; 
       }; 

     } 
    } 

    public void clearConsole() { 
     for (int i = 0; i < 25; i++) { 
      System.out.println(); 
     } 
    } 


    public void addItem() { 
     System.out.println("Please type the item to add to the To-Do List"); 
     //The skip gets over the leftover newline character 
     inputread.skip("\n"); 
     String newItem = inputread.nextLine(); 
     toDoList.add(newItem); 
     System.out.println("Your item has been added! Type any key and press Enter to continue"); 
     String discardMe = inputread.next(); 
     menu(); 
    } 

    public void displayList(boolean finish) { 

     if (toDoList.isEmpty()) { 
      System.out.println("Add an activity."); 

     } else { 
      for (String listItem: toDoList) { 
       System.out.println(listItem); 
      } 
     } 
     if (finish) { 
     System.out.println(); 
     System.out.println("This is your list. Type any key and press Enter to continue"); 
     String discardMe = inputread.next(); 
     } 

    } 

    public void deleteItem() { 
     if (toDoList.isEmpty()) { 
      System.out.println("For fuck's sake, add an activity."); 
     } else { 
      System.out.println("Please choose the number of the line you want to delete:"); 
      displayList(false); 
      int userinput = inputread.nextInt(); 
      int listPos = userinput - 1; 
      toDoList.remove(listPos); 
      System.out.println("That item has been deleted. Type any key and press Enter to continue."); 
      String discardMe = inputread.next(); 
     } 
     menu(); 
    } 

    public void saveList() throws IOException { 
     System.out.println("Saving list..."); 
     PrintWriter writer = new PrintWriter("list.txt", "UTF-8"); 
     for (String listItem : toDoList) { 
      writer.println(listItem); 
     } 
     writer.close(); 
     System.out.println("List saved! Type any key and press Enter to continue"); 
     String discardMe = inputread.next(); 
     menu(); 

    } 

    public void loadList() throws IOException { 
     System.out.println("Loading list..."); 

     File loadFile = new File("list.txt"); 
     Scanner scanner = new Scanner(loadFile); 
     while (scanner.hasNext()) { 
      String item = scanner.nextLine(); 
      toDoList.add(item); 
     } 
     System.out.println("List loaded! Type any key and press Enter to continue"); 
     String discardMe = inputread.next(); 
     menu(); 
     scanner.close(); 
    } 
} 

클래스 H2db :

package com.company; 

import java.sql.*; 
import java.util.ArrayList; 
import java.util.Scanner; 


public class H2db { 
    Scanner inputread = new Scanner(System.in); 
    ArrayList<String> toDoList = new ArrayList<String>(); 

    public void connect(){ 

     try { 
      Class.forName("org.h2.Driver"); 
      Connection conn = DriverManager.getConnection("jdbc:h2:~/toDo", "user", ""); 
      Statement stat = conn.createStatement(); 

      stat.execute("CREATE TABLE IF NOT EXIST 'todo'(id int NOT NULL AUTO_INCREMENT primary key, item varchar(255))"); 
     } 
     catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 

    } 

    public void addItems() { 
     PreparedStatement addstat; 

     try { 
      Class.forName("org.h2.Driver"); 
      Connection conn = DriverManager.getConnection("jdbc:h2:~/toDo", "user", ""); 

      System.out.println("Please type the item to add to the To-Do List"); 
      inputread.skip("\n"); 
      String newItem = inputread.nextLine(); 
      addstat = conn.prepareStatement("INSERT INTO toDo (item)" +"VALUES (?)"); 
      addstat.setString(1, newItem); 
      addstat.executeUpdate(); 

      System.out.println("Your item has been added! Type any key and press Enter to continue"); 
      String discardMe = inputread.next(); 
      ToDo.menu(); 
     } 
     catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 

    } 
} 

어떤 도움이 좋지 않을까, 감사합니다. 나는 이것이 지식의 격차라는 것을 알고 있지만, 나는이 개념이 무엇이든간에 무엇이든 파악할 수는 없다.

+0

정적으로 선언하는 곳은 어디입니까? –

+0

[정적이 아닌 변수는 정적 컨텍스트에서 참조 할 수 없습니다] (http://stackoverflow.com/questions/2559527/non-static-variable-cannot-be-referenced-from-a-static-context) – Johan

+0

@Sridhar DD 아니, 그게 문제 야. 메서드를 정적으로 변경하려고하면 다른 모든 메서드가 중단됩니다. ToDo의 인스턴스와 함께 사용하여 정적 일 필요가없는 방법이 있습니까? 내가 말했듯이, 그 개념은 저를 넘어서는 것입니다. –

답변

1

나는 당신이 객체 지향 프로그래밍의 기초를 놓치고 있다고 생각한다. 먼저 자신에게 물어보십시오 : ToDo 클래스가 나타내는 객체는 무엇입니까? 코드를 보면 그것은 GUIManager입니다.

제대로 작동하는 GUIManager에는 H2DBManager라는 이름의 데이터베이스 (현재 H2db 클래스)에 데이터를 저장할 수있는 다른 개체가 필요합니다. 이것은 GUIManager가 생성자에서 H2DBManager 즉 h2DBManager를 인스턴스화하고 필요할 때 정적 메소드가 아닌 일반 메소드를 사용해야 함을 의미합니다. H2DBManager 클래스가 태스크를 완료하면 (즉, addItems 메소드에 무언가를 저장하는 것이 완료되면) 컨트롤 플로우가 클래스 GUIManager에 자동으로 리턴되므로 클래스 H2DBManager에서 명시 적으로 GUIManager 조작 (정적 또는 정적이 아닌)을 호출 할 필요가 없습니다.

+0

감사합니다. 답이 많은 의미가 있으며, 내 생각의 근본적인 결함을 해결하기 때문에 올바른 대답으로 선택합니다. –

0

H2db의 인스턴스가 하나만 필요한 것 같습니다. 이 경우 당신은 싱글 패턴을 사용하여 고려할 수 있지만, 지금처럼 빠르게 모든 단순히 적절한 위치에 키워드 static를 추가하여 작동시킬 것 :

static Scanner inputread = new Scanner(System.in); 
    static ArrayList<String> toDoList = new ArrayList<String>(); 

    public static void connect(){ 

    public static void addItems() { 
+0

당신이 언급 한 두 가지 기능을 위해 일했지만, H2db 내에서 ToDo.menu()를 호출 할 때 도움이되지 않는 것 같습니다. 메뉴()를 정적으로 만들려고하면 모든 것이 손상됩니다. –

+0

@Vladimir Marenus'menu()'를'static'으로 변경하면'menu()'에 의해 호출 된 다른 모든 메소드를'static'으로 변경해야합니다. – Titus

0

대답은 간단하다. 클래스 이름에 따라 H2db.addItems()를 호출하려면 H2db 클래스의 addItems() 메소드를 정적으로 선언해야합니다. 또는

H2db 클래스의 인스턴스 (개체)를 만들 수 있습니다.

H2db myObject = new H2db(); 
myObject.addItems(); 

고정 된 메서드 또는 특성을 선언 할 때. 그런 다음 클래스 변수/메소드가됩니다. H2db.addItems()라고 부를 수 있습니다.

메소드/속성을 정적으로 선언하지 않는 경우. 그런 다음 인스턴스 변수/메소드가됩니다. 위의 코드 샘플에서 언급 한 것처럼 호출 할 수 있습니다. 인스턴스 (객체) 이름을 기준으로합니다.

+0

그것은 좋은 연습으로 간주됩니까? 나는 그것이 주관적인 질문이라는 것을 알고 있지만, 목록에 항목을 추가해야 할 때마다 객체를 생성하는 것만으로 "외모를 보입니다". 내가 다른 나쁜 일을하고 있기 때문에 이것이 필요합니까? 아니면 진정한 방법일까요? –

+0

사실은 컨텍스트에 따라 다릅니다. 클래스를 생성하고 클래스/클래스를 디자인 할 때 클래스/애트리뷰트가되어야하는 메소드/애트리뷰트를 결정할 때는 정적으로 선언하십시오. 그렇지 않으면 인스턴스 변수/메소드로 간주하고 정적으로 선언하지 마십시오. 예를 들어, 클래스의 상수는 모든 인스턴스 (객체)에서 사용되므로 정적으로 선언되며 변경되지 않아야합니다. – RehanZahoor

관련 문제