Java - Referencing objects from another method - java

This is a little adventure game I'm working on. I'm just trying to create a 3x3 matrix that the player can move around in. But, in the game loop (which doesn't loop yet, I know,) I can't reference the Player or Room objects I created with the init() method. (I have separate class files for Player and Room objects, they work fine.) When I try to run this code:
import java.util.Scanner;
public class Adventure
{
public final static int maxCol = 2;
public final static int maxRow = 2;
public static void init()
{
Scanner keyboard = new Scanner(System.in);
//instantiate rooms
final Room[][] maze = new Room[maxCol+1][maxRow+1];
final Player player = new Player("",1,1);
for(int i = 0; i <= maxCol; i++)
{
for(int j = 0; j <= maxRow; j++)
{
maze[i][j] = new Room("room");
}
}
//room names
maze[0][0].setDesc("Alleyway - West");
maze[0][1].setDesc("Alleyway - East");
maze[0][2].setDesc("Back Entrance");
maze[1][0].setDesc("Back Room");
maze[1][1].setDesc("Hallway");
maze[1][2].setDesc("Bar - North");
maze[2][0].setDesc("Bathroom");
maze[2][1].setDesc("By An Arcade Machine");
maze[2][2].setDesc("Bar - South");
//get player name
System.out.print("What is your name? ");
String nameInput = keyboard.nextLine();
//create player object
player.setName(nameInput);
player.display();
}
public static void main(String args[])
{
init();
playGame();
}
public static void playGame()
{
System.out.print(maze[player.getXPos()][player.getYPos()].getDesc());
}
}
I get these errors:
Adventure.java:54: error: cannot find symbol
System.out.print(maze[player.getXPos()][player.getYPos()].getDesc());
^ symbol: variable maze location: class Adventure Adventure.java:54: error: cannot find symbol
System.out.print(maze[player.getXPos()][player.getYPos()].getDesc());
^ symbol: variable player location: class Adventure Adventure.java:54: error: cannot find symbol
System.out.print(maze[player.getXPos()][player.getYPos()].getDesc());
^ symbol: variable player location: class Adventure 3 errors
What am I doing wrong? Thank you :)

This is an issue of scope! Java has particular rules for how something can be accessed, depending on where it is declared. If you declare something inside a method, then you can only access it inside that method.
public void doSomething() {
String str = "Hello";
// when doSomething ends, str is lost!
}
To solve this, you can declare your variable outside of the method, in the global level.
String str = "Hello";
public void doSomething() {
str = "Hello";
}
Notice, you've declared it outside of the method, but you've defined it inside the method.
Extra Reading
The big one is Java scope.

Scope of your maze variable is limited to the method init thus it can't be found in your playGame method. Update init to return the maze (Room[][]) or declare it static. In fact you need to do this for your player object too.

Related

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.
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
}
The other objects in your array should not change. Can you add some more code for more context?
As far as I can understand you, you are doing something like:
public class Main {
public static String[] strings = new String[2];
public static void main(String[] args) {
strings[0] = "test";
System.out.println(strings[1]);
}
}
In my example output is "null" as expected.
How do I get rid of all this static?
Just create instances of your objects in the main function.
GameBoard[] gameboard = new GameBoard[9];
For what you describe to happen all the elements of the gameboard array must be set to the same object (nothing to do with the array being static), check your code where you populate the gameBoard array with new instances of the GameBoard class for a bug that could cause the same instance to be written to all elements (or post that code here so people can see the problem).

Incompatible types when creating new string array and cannot find symbol when accessing another class variable

Incompatible types when creating new string array and cannot find symbol when accessing another class variable.
I have two classes:
Sistem
MataKuliah
Sistem class:
/*
Test array
*/
import java.util.Scanner;
class Sistem
{
public static void main (String args[]){
int counter = 0, jumlahMk;
String[] namaMk = new String[jumlahMk];
Scanner in = new Scanner(System.in);
MataKuliah mk = new MataKuliah();
jumlahMk = in.nextInt();
in.nextLine();
while(counter<jumlahMk){
namaMk[counter] = (new String[jumlahMk]);
namaMk[counter] = in.nextLine();
counter++;
}
mk.printNamaMatkul(namaMK);
}//end main
}//end class
MataKuliah class:
/*
MataKuliah class
*/
class MataKuliah{
void printNamaMatkul(String[] namaMk){
System.out.println(Sistem.namaMk);
}
}
I know it's basic, please help me! :)
You can only access fields in another class. A better approach is to pass the data you want to use, which is what you actually did.
void printNamaMatkul(String[] words){
System.out.println(Arrays.toString(words));
}
The name of the parameter doesn't have to match the argument you passed to it. i.e. you can write
printNamaMatkul(namaMk);
but it would make more sense to make the name of the method generic
void printArray(String[] words){
System.out.println(Arrays.toString(words));
}
printArray(namaMk);
There are a couple of issues with your program.
namaMk[counter] = (new String[jumlahMk]); This statement is incorrect as you are trying to convert String to String[] here.
You have not given the size of namaMk Array.
You are trying to refer the private member of another class by doing System.out.println(Sistem.namaMk);
You are creating the object of class MataKuliah directly in static main block.
You need to correct all the above problem to get your code running.
Here is the corrected code snippet:
public class MataKuliah {
public void printNamaMatkul(String[] namaMK) {
System.out.println(Arrays.toString(namaMK));
}
}
class Sistem
{
public static void main (String args[]) {
/* Create a new instance of Sistem */
Sistem sistem = new Sistem();
sistem.run();
}
private void run() {
int counter = 0, jumlahMk;
Scanner in = new Scanner(System.in);
/* This will be valid now */
MataKuliah mk = new MataKuliah();
jumlahMk = in.nextInt();
/* Create the String[] Array */
String[] namaMk = new String[jumlahMk];
in.nextLine();
while(counter < jumlahMk){
namaMk[counter] = in.nextLine();
counter++;
}
mk.printNamaMatkul(namaMk);
}
}
Input:
3
foo
bar
foobar
Output:
[foo, bar, foobar]

Java - Calling private arraylist from class [duplicate]

This question already has answers here:
Is it possible in Java to access private fields via reflection [duplicate]
(3 answers)
Closed 7 years ago.
My template opens with a menu of options and the user inputs something between 1-3 to select one of the three options.
When the user chooses option 1, it asks them to input a number teamNumber. One must instantiate the class Team, then it writes it to an arraylist.
If there is at least one number in numberList, the user can select option 2. It asks them to input any of the numbers from the arraylist and searches it. If the number they input is found, then you input a String teamMemberFirstName and a char firstInitialLastName. Then it will write the input to a private arraylist located in another class TeamMember.
Once they have input the info in option 1 and 2, they can choose option 3. It allows you to print the list of inputted names based on which team number you put them on.
I am not sure how, in option 3, to call the private arraylist from the TeamMember class teamList. Any guidance on how to proceed with this step? My code is below.
Main class:
public class Main {
public static void main(String[] args) {
int choosing;
Scanner scan = new Scanner(System.in);
String input;
int teamNumber;
boolean stayInLoop;
ArrayList<Team> numberList = new ArrayList<Team>();
do {
stayInLoop = true;
System.out.println("1. Add a new team");
System.out.println("2. Add a new team member");
System.out.println("3. View teams");
input = scan.nextLine();
if (input.equals("1")) {
System.out.println("Enter a team number:");
teamNumber = scan.nextInt();
scan.nextLine();
Team addTeam = new Team(teamNumber);
numberList.add(addTeam);
}
if (input.equals("2")){
boolean foundIt = false;
boolean valid = true;
System.out.println("Team number:");
teamNumber = scan.nextInt();
scan.nextLine();
for (int a = 0; a < numberList.size() && foundIt == false; a++){
Team addTeam = numberList.get(a);
if (addTeam.findTeam() == teamNumber) {
foundIt = true;
System.out.println("Enter first name of team member:");
String teamMemberFirstName = scan.nextLine();
System.out.println("Enter first initial of last name:");
char firstInitialLastName = scan.nextLine().charAt(0);
TeamMember inputTeamMember = new TeamMember(teamMemberFirstName, firstInitialLastName);
inputTeamMember.addMember(inputTeamMember, valid = true);
System.out.println("Success!");
}
}
if (foundIt == false) {
System.out.println("Try again.");
}
}
if (input.equals("3")){
for (int a = 0; a < numberList.size(); a++) {
Team addTeam = numberList.get(a);
//Not sure what to put where there are ????'s - I tried a few ideas and stuff I found online, but nothing worked
//I assume I call the method/class here????
System.out.println("Team: " + addTeam.findTeam() + " Members: " +
"I will put the member called from the arraylist here????");
}
}
}while (stayInLoop == true;)
}}
TeamMember class:
public class TeamMember {
private final String teamMemberFirstName;
private final char firstInitialLastName;
private ArrayList<TeamMember> teamList = new ArrayList<>();
public TeamMember(String teamMemberFirstName, char firstInitialLastName) {
this.teamMemberFirstName = teamMemberFirstName;
this.firstInitialLastName = firstInitialLastName;
}
public int addMember(TeamMember member, boolean valid) {
valid = teamList.add(member);
return teamList.size();
}
}
You cannot directly access private fields from other classes. Either move your list to the Team class or create a getter to retrieve the list.
In a public class, you can return a private object in a public method. This seems like the easiest way in this project. Add a new method to your TeamMember class, and have it return teamList:
//inside your TeamMember class, anywhere after you assign the private variable
public static ArrayList show(){
//the static keyword, in short, will make the method callable without a class instance.
return teamList;
}
Since the TeamMember method show() is now static, you should be able to simply call TeamMember.show() and get the ArrayList.
Important note: In order for this to work, you must make the private arraylist static too. A static object cannot call a non-static object.
This will turn it into private static ArrayList<TeamMember> teamList = new ArrayList<>();
In the Main class, like I said above, simply call TeamMember.show(). You do not need to create an instance.
If you change your teamList to public instead of private your Main class will be able to access the variable. When you make something private in Java you're basically making that instance variable accessible only through the class that it's instantiated in. If you want the variable to be visible to other classes for reference you should make it public
Since the assignment calls for it, you're going to need to define a getter and setter for your 'teamList' variable.
public void setArray(ArrayList newTeamList){
teamList = newTeamList;
}
public ArrayList getArray(){
return teamList;
}
This'll allow you to access the private variable through the methods

Placing an Object into and Object Array, which is inside another Object Array

So I'm new to coding/Java and I'm working on this project. My assignment is to create 3 different classes (which I have here) and make a them cooperate. I've successfully made my FishTankManagerApp class retrieve a new Fish object and I'm trying to figure out how to put it in a FishTank object.
My FishTank class only is only there to create an array object which can hold 5 fish (I think I've done this correctly). In my FishTankManagerApp class, I've created an array of 10 of these FishTank Objects.
My question which I cant figure out for the life of me is how do I place the Fish objects into a specfic FishTank object after they've been created (I've made a note at the end of the code where I've ran into a problem).
Essentially I know I'm trying to put an object I've created inside of and array which contains another array where fish objects can be stored... I think....
Any help would be much appreciated! Thank you!
import java.util.Scanner;
public class Fish {
private static Scanner stdin = new Scanner(System.in);
private String userInput;
private int userInput2;
public boolean mean;
public String name;
public Fish(){
System.out.println("What is your fishes name?");
userInput = stdin.next();
this.name = userInput;
System.out.println("Is this fish aggressive?\n"+
"(1)Yes\n(2)No");
userInput2 = stdin.nextInt();
if (userInput2 == 1)
this.mean = true;
else
this.mean = false;
}
}
public class FishTank {
public FishTank(){
Fish[] tank = new Fish[5];
}
}
import java.util.Scanner;
public class FishTankManager {
private static Scanner stdin = new Scanner(System.in);
private static int userInput;
private static FishTank[] tanks = new FishTank[10];
public static void main (String[] args) {
while (true){
System.out.println("Welcome to your new fish tank manager!\n"+
"What would you like to do?\n"+
"(1)Add a Fish\n(2)Move a Fish\n"+
"(3)Check a tank");
userInput = stdin.nextInt();
if (userInput == 1){
Fish fish = new Fish();
System.out.println(fish.name);
System.out.println(fish.mean);
changeTank(fish);
}
else if(userInput ==2){
}
else{
}
}
}
private static void changeTank(Fish fish){
System.out.println("Which tank would you like to put this fish in? (1-10)");
userInput = stdin.nextInt();
tanks[userInput] = fish;
// This last line is where I'm confused on how to put the fish() object into a tank which I've created.
}
}
I'd recommend adding a method to your FishTank to make adding the fish easy. Maybe something like this:
public FishTank(){
private Fish[] tank = new Fish[5];
public boolean addFish(Fish fish) {
// ... add code here to put the fish to the tank array
// return true if there was room in the tank, false otherwise
}
}
Note that the tank variable is now private. It's generally a good idea to keep member variables private in Java, and use methods to access them.
Then, where you've got the comment you mentioned, you can just call the new method:
boolean addedSuccessfully = tanks[userInput].addFish(fish);
You may not need to return the boolean as I'm showing, but it might be handy if you need to check whether the array (i.e. the tank) had room for the new fish.
Currently, what you're doing is setting the FishTank object equal to a Fish instance - not adding it to the tank variable inside of FishTank.
Right now, you have no way of accessing the tank variable inside of the FishTank class. What you need to do is make it a global variable and provide accessor/modifier methods. For example:
public class FishTank {
private Fish[] tank;
private int numFish;
public FishTank(){
this.tank = new Fish[5];
this.numFish = 0;
}
public void add(Fish f){
if(this.numFish >= 5){
//handle "tank is full" case
}
else{
numFish++;
this.tank[numFish] = f;
}
}
}
Then invoke add on the desired FishTank object:
tanks[userInput].add(fish);

How to write a 3 class program and have the main class trigger methods in the other two

I have to write a program with 3 classes and lots of different methods.
I've written a simpler example to try and get an idea where I am going wrong
First class (music) is defining a music object with three data types. And should have a method to print the contents of an array.
the second class (musicArray) has all the data for the array and should build the array when the third class tells it too.
the third class(searchclass) has the main method it should tell the second class to make the array then with user input search the array for songs that match the rating.
import java.util.Arrays;
public class Music extends musicArray {
private String songTitle;
private double songLength;
private int rating;
static String everything;
public Music(String songTitle, double songLength, int rating) {
this.songTitle = songTitle;
this.songLength = songLength;
this.rating = rating;
}
public String getsongTitle()
{
return songTitle;
}
public double getsongLength()
{
return songLength;
}
public int rating()
{
return rating();
}
#Override
public String toString() {
return "music{"+ "songTitle= " + songTitle + ", songLength= "
+ songLength + ",rating=" + rating + '}';
}
public Music[] printsonglibrary(char[][] songDetails){
for (int count = 0; count <= 6; count++)
{
return System.out.println(songDetails[count]);
System.out.println(" ");
}
}
}
public class musicArray extends Searchclass{
static Music song1 = new Music ("achy breaky", 5.32, 10);
static Music song2 = new Music ("billy",1.2, 8 );
static Music song3 = new Music ("hello", 1.5, 9 );
static //Create array and make posistion 0 = song1
Music[] songDetails ={song1,song2,song3};
import java.util.Scanner;
public class Searchclass {
public static void main(String[] args) {
for(int count = 1; count <= songDetails.length; count++){
system out put for debugging
System.out.println(songDetails.length);
System.out.println(songDetails[count - 1]);}
}
/* public String songSeach(){
System.out.println("what rating of song do you want to search for?");
Scanner keyboard = new Scanner(System.in);
int searchValue = keyboard.nextInt();
if searchValue == rating in array use the printsonglibrary
method in the music class to print the array entry
*/
}
}
If I have the main method in the musicArray class I can print the array
So the question is how do I make the Songdetails array available in the seachclass?
You shouldn't directly expose any variables of one class to another. Instead consider giving the MusicArray class (note that by convention class names should begin with a capital letter) a public method, say public void printOutSongDetails() that would print out the contents of the array. Your main method can then call this method off of the MusicArray object that it has created. e.g.,
Edit 1
Also, the Music class should most definitely not extend the MusicArray class for there is no way that a Music object should behave like a MusicArray object. And on the same token, MusicArray should not extend the SearchClass.
Edit 2
Note that there are several other significant issues with your code that each one would prevent it from compiling, and this suggests that you should modify how you program (if you can't use an IDE). Try to compile early and often, and only add new code to the program after fixing any compilation errors so that the current code base compiles.
Edit 3
A small code example of what I was describing above.
class SearchClass {
public static void main(String[] args) {
MusicArray musicArray = new MusicArray();
musicArray.addMusic(new Music("Foobars Unit", 10.4, 5));
musicArray.addMusic(new Music("Spamalot", 11.0, 7));
//... etc ...
musicArray.printOutSongDetails();
}
}
Also, you'll probably not want those static Music variables but rather give MusicArray a method to add Music to its array, a public void addMusic method that accepts a Music object as a parameter.
One way is to make it public public Music[] songDetails ={song1,song2,song3};
A better way is to provide getter:
public Music[] getSongDetails() {
return songDetails;
}

Categories

Resources