2016-06-20 5 views
1

Я проделал здесь некоторое время для решения, но не могу найти его. Я попробовал these ones и многие другие, и я столкнулся с той же проблемой.Вызов нестатического метода (в другом классе) из статического

Я пытаюсь сделать простой текст игры, и я бегу в вопрос, где у меня есть основной класс и класс под названием «Gameboard», что у меня есть как массив, определенной как это:

static GameBoard[] gameboard = new GameBoard[9];

Теперь это работает нормально, пока я не попытаюсь изменить характеристики одного из этих объектов массива. Я буду делать:

gameboard[input].setState(2); 

и конкретный экземпляр игрового поля, которые должны изменить не будет только одна: все они изменяются, когда я делаю это. Это странно. Только gameboard[**input**] должен измениться, а не все 9 экземпляров игрового поля. Любая переменная и метод, который у меня есть, являются «статическими», но из-за основного метода (public static void main ...) все, кажется, должно быть статическим. Как мне избавиться от всего этого статического?

GameBoard Класс

package com.name.tictactoe; 

public class GameBoard { 
char[] States = {'N','X','O'}; 
char state; 

public void setState(int s){ 
    state = States[s]; 
} 
public char getState(){ 
    return state; 
} 
} 

Основной класс (названный Game)

package com.name.tictactoe; 

import java.util.Scanner; 

public class Game { 

static boolean turn, win; 
static GameBoard[] gameboard; 
static Scanner kb = new Scanner(System.in); 
static int input; 

public static void main(String[] args){ 
    gameboard = new GameBoard[9]; 
    reset(); 
    displayStates(); 
    askTurn(); 
    displayStates(); 
    askTurn(); 

} 

public static void askTurn() { 
    System.out.println(); 
    System.out.println(); 
    System.out.println("Where do you want to go? Use the numbers shown, where the first segment is the top and the last is the bottom - left to right."); 
    input = kb.nextInt(); 
    if(input > 8){ 
     System.out.println("Input out of bounds. Game over by default."); 
     try { 
      Thread.sleep(1000000000);} catch (InterruptedException e) {e.printStackTrace();} 
    } 
    gameboard[input].setState(2); 
} 

public static void reset(){ 
    for(int i = 0; i < 9; i++){ 
     gameboard[i].setState(0); 
    } 
} 

public static void displayStates(){ 
    for(int i = 0; i < 9; i++){ 
     System.out.print(gameboard[i].getState() + " "); 
     if(i ==2 || i ==5){ 
      System.out.print(" II "); 
     } 
    } 
    System.out.println(); 
    for(int i = 0; i < 9; i++){ 
     System.out.print(i + " "); 
     if(i ==2 || i ==5){ 
      System.out.print(" II "); 
     } 
    } 
    System.out.println(); 
} 

}

UPDATE: текущие ответы не работают. Хотя Eclipse не понимает этого, делая GameBoard нестатическим, вызывает исключения с нулевым указателем, когда упоминается какой-либо метод в нем.

+0

«КАЖДАЯ переменная и метод, который у меня есть, являются« статическими »» - хорошо, что это не очень хорошая идея, если вы хотите, чтобы разные экземпляры имели разные состояния. Вы понимаете, что означает 'static'? –

+0

Ваша проблема в том, что вы пытаетесь иметь экземпляры 'static', которые являются противоречиями. 'setState' не меняет их всех, у вас есть только один набор статических переменных для обновления. – Grayson

+0

Не полностью, хотя я изучил Java более 2 лет назад. Я не использовал Java совсем недавно, но я не помню, чтобы когда-либо учился «статический». Английский говорит мне, что «статический» неизменен, но я думаю, что это _slightly_ off, так как значение может измениться. – Bobdabiulder

ответ

2

static переменная принадлежит к классу , а не объект, поэтому, конечно, все ваши GameBoard с подвержены воздействию!

Просто потому, что вы находитесь в статическом методе, не означает, что вы не можете манипулировать переменными экземпляра. Во-первых, сделайте все в своем классе не статическим (если вам действительно не нужны некоторые значения, разделяемые во всех экземплярах). Сюда входят ваши переменные экземпляра и методы getter/setter.

Если ваша программа работает исключительно с main, то сохраняйте свой объект GameBoard[] статическим.Затем, когда вы делаете этот вызов метода:

gameboard[input].setState(2); 

Это изменит только состояние GameBoard по индексу input.

Edit:

Чтобы создать экземпляр GameBoard[] с основными GameBoard объектов внутри него, вы можете сделать это в начале вашего main метода:

for(int x=0; x<gameboard.length; x++) { 
    gameboard[x] = new GameBoard(); //Assuming you want to use the default constructor 
} 
+0

Не работает. Я получаю исключение нулевого указателя, когда вызываю какой-либо нестатический метод другого класса. Сожалею. – Bobdabiulder

+0

Вы создавали экземпляр каждого 'GameBoard'? Помните, что объявление GameBoard [] gameboard = new GameBoard [9]; 'создает массив для хранения' GameBoard', но массив пуст. – Zircon

+0

Спасибо! Это работает безупречно! Теперь я могу сделать игру более эффективной, обнаружить победу и, в конечном итоге, получить рабочий AI. :) :) – Bobdabiulder

1

Другие объекты в массиве не должны меняться. Можете ли вы добавить еще какой-нибудь код для большего контекста?

Насколько я понимаю, вы делаете что-то вроде:

public class Main { 
    public static String[] strings = new String[2]; 

    public static void main(String[] args) { 
     strings[0] = "test"; 
     System.out.println(strings[1]); 
    } 
} 

В моем примере вывода является «нулевым», как и ожидалось.

Как избавиться от всего этого статического?

Просто создайте экземпляры объектов в основной функции.

GameBoard[] gameboard = new GameBoard[9];

1

За то, что вы описываете случиться все элементы массива игрового поля должны быть установлены на один и тот же объект (ничего не делать с статическим массивом), проверьте свой код, в котором вы заполняете массив gameBoard новыми экземплярами класса GameBoard для ошибки, которая может вызвать один и тот же экземпляр t o записываться во все элементы (или размещать этот код здесь, чтобы люди могли видеть проблему).

Смежные вопросы