Search code examples
javamethodsstaticinstances

Calling non-static method (in a different class) from static


I've done some looking around on here for a solution, but I can't find one. I tried these ones and many others, and I run into the same issue.

I am trying to make a simple text game, and I run into the issue where I have a main class, and a class called "gameboard" that I have as an array defined like this:

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

Now, this works fine until I try to change the characteristics of a single one of these array objects. I will do:

gameboard[input].setState(2);

and the specific instance of gameboard that should change will not be the only one: all of them change when I do this. It's weird. Only gameboard[**input**] should change, not all 9 of the gameboard instances. EVERY variable and method I have is "static", but because of the main method (public static void main...), everything seems to have to be static. How do I get rid of all this static?

GameBoard Class

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

Main class (called 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: The current answers don't work. Although Eclipse doesn't realize this, making GameBoard non-static causes null pointer exceptions when any method in it is referenced.


Solution

  • A static variable belongs to the class, not the object, so of course all of your GameBoards are being affected!

    Just because you're in a static method doesn't mean you can't manipulate instance variables. First, make everything in your GameBoard class non-static (unless you really do need some of the values shared across all instances). This includes your instance variables and your getter/setter methods.

    If your program works exclusively from the main method, then keep your GameBoard[] object static. Then, when you make that method call:

    gameboard[input].setState(2);
    

    This will change only the state of the GameBoard at index input.

    Edit:

    To instantiate your GameBoard[] with basic GameBoard objects inside of it, you can do this at the beginning of your main method:

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