Illegal Self Reference in creation of class - java

I am pretty new to Java, my code is giving me the error "Illegal Self reference" in the lines below on Charmander/Squirtle/Bulbasaur.moveList
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
Here is my code
public class Pokemon_Builder {
public static void main(String[] args) {
Move_Builder mb = new Move_Builder();
Charmander.moveList.add(mb.Ember);
Charmander.moveList.add(mb.Scratch);
Charmander.moveList.add(mb.Willowisp);
Charmander.moveList.add(mb.Recover);
Squirtle.moveList.add(mb.Bubble);
Squirtle.moveList.add(mb.Tackle);
Squirtle.moveList.add(mb.Powdersnow);
Squirtle.moveList.add(mb.Recover);
Bulbasaur.moveList.add(mb.Vinewhip);
Bulbasaur.moveList.add(mb.Poisonpowder);
Bulbasaur.moveList.add(mb.Tackle);
Bulbasaur.moveList.add(mb.Recover);
System.out.println(Charmander.moveList.size());
}
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
}
And here is the code for the Pokemon Class:
import java.util.LinkedList;
import java.util.List;
public class Pokemon{
String type;
String name;
int health;
List<Move> moveList = new LinkedList<Move>();
public Pokemon(String type, String name, int health, LinkedList moveList) {
this.type = type;
this.name = name;
this.health = health;
this.moveList = moveList;
}
public void getInfo (){
System.out.println("Pokemon Name "+ this.name);
System.out.println("Your Pokemon's type "+ this.type);
System.out.println("Your Pokemon's health "+ this.health);
}
public void addMove(Move toAdd){
if (moveList.size() < 5){
moveList.add(toAdd);
}
else{System.out.println("Can't learn any more moves!");
}
}
}
Thanks in advance for the help

In your class Pokemon_builder you create 3 pokemon, while creating those pokemon you provide a moveList. Those movelists are created when the pokemon is created. Meaning what you now try to do is pass a field of a pokemon to the constructor for that pokemon.

As your Pokemon object is instantiating itself the the static member object creation runs before the constructors do. You are trying to create an object called Charmander and pass into Charmander's constructor a reference to a static "movelist" object within Charmander. You are doing this BEFORE Charmander has completed its object instantiation process. Thus you are trying to create an object that needs a reference within itself to "construct" itself.

Related

Cannot make a static reference to the non-static field players

I'm making a program in java to register players and add them in an arraylist. My method for adding players is this:
void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
my problem is that i don't know where to put
ArrayList<Player> players = new ArrayList<>();
if i have it in main, the method doesn't know what players is, but if i have it in the class i get a "Cannot make a static reference to the non-static field players" exception, when i try to print it from main. What's the best way of solving this.
Update: thanks for the help, i realized that since my command loop is already running on an instanced version of my class there is actually no problem, there was only a problem when i tried to test my method outside the instanced command loop.
If you'd like to have it at the class level, escape the static context.
public class YourClass {
ArrayList<Player> players = new ArrayList<>();
public static void main(String[] args) {
new YourClass(); // or YourClass yourClass = new YourClass();
}
// Create an instance of YourClass to leave the static context
public YourClass() {
registerNewPlayer();
}
public void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
System.out.print("Weight?> ");
int weight = input.nextInt();
Player player = new Player(name, game, age, weight);
players.add(player);
}
}
I thinik this is the best solution for your problem. I hope it helps :)
Your Player class:
public class Player {
private static ArrayList<Player> _players = new ArrayList<Player>();
private String name;
private String game;
private int age;
private int weight;
public Player(String name, String game, int age, int weight){
this.name = name;
this.game = game;
this.age = age;
this.weight = weight;
}
public static void AddPlayer(Player player){
_players.add(player);
}
public static ArrayList<Player> getPlayers(){
return _players;
}
}
Now you can create some players and get them as follow:
... main ...
.
.
.
Player p1 = new Player("Name1", "Game1", 20, 70);
Player p2 = new Player("Name2", "Game2", 30, 80);
Player p3 = new Player("Name2", "Game3", 25, 73);
Player.AddPlayer(p1);
Player.AddPlayer(p2);
Player.AddPlayer(p3);
ArrayList<Player> allPlayers = Player.getPlayers();
.
.
.
Let me know if it is working for you !
The error you get is because you are trying to access a non-static variable (i.e. a value or object that exists only in instances of that class) from outside of such an instance. What you can do is to create an object of that class to be able to access the players through it:
public class Demo {
private List<Player> players = new ArrayList<>();
public static void main(String[] args) {
Demo demo = new Demo();
demo.registerNewPlayer();
System.out.println(demo.players);
}
private void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
}
By creating an object of the class and executing the method as well as access the variable through it, allows you to do what you want (if I understood correctly that is).
Further reading material:
Java: when to use static methods
Type List vs type ArrayList in Java (you may have noticed that I changed the type of players to List<Player> from ArrayList<Player>)
What is the difference between public, protected, package-private and private in Java? (you may have noticed the private keyword on the list and the method)
Globally declare the list.
ArrayList<Player> players = new ArrayList<>();

How to have a driver class inherit certain attributes of a super class?

I am trying to have my driver class inherit the information from two different classes. I have to use the formula className objectName = new className(input parameters) to instantiate one of the classes. But I keep getting the symbol not recognized error.
I'm not sure how I could fix this problem. I tried creating an import statement, but the other two classes are part of the same package. I have also tried using the extends keyword, but also noluck
public class Corgi extends Dog {
// additional class variables
private static int weight;
private static int age;
// constructor
public Corgi(String type, String breed, String name, int pounds, int years) {
// invoke Dog class (super class) constructor
super(type, breed, name);
weight = pounds;
age = years;
}
// mutator methods
public static int setWeight(int pounds){
weight = pounds;
return pounds;
}
public static int setAge(int years){
age = years;
return years;
}
// override toString() method to include additional dog information
#Override
public String toString() {
return (super.toString() + "\nThe Corgi is " + age +
" years old and weighs " + weight + " pounds.");
}
}
public class Dog {
// class variables
private static String type;
private static String breed;
private static String name;
private static String topTrick;
// constructor
public Dog(){
type = "none";
breed = "none";
name = "none";
}
// methods
public static String setTopTrick(String trick){
topTrick = trick;
return trick;
}
// method used to print Dog information
public String toString() {
String temp = "\nDOG DATA\n" + name + " is a " + breed +
", a " + type + " dog. \nThe top trick is : " +
topTrick + ".";
return temp;
}
}
public class Main
{
public static void main(String[] args) {
Corgi tricker = new Corgi();
tricker.setTopTrick("Backflip");
System.out.println(tricker);
}
}
I am expecting to be able to have the main class inherit Corgi's info with the Corgi tricker = new Corgi(); statement. But I keep getting the error:
Main.java:6: error: cannot find symbol
Corgi tricker = new Corgi("Hunting", "Shiba", "Simon", 30, 7);
^
symbol: class Corgi
location: class Main
In your Corgi class you need to remove variables from super()
public Corgi(String type, String breed, String name, int pounds, int years) {
// invoke Dog class (super class) constructor
super();
weight = pounds;
age = years;
}
2.Then you have to add values in Corgi(); which is in `Main class'
public static void main(String[] args) {
Corgi tricker = new Corgi("puppy", "Husky", "Alex", 15, 1);
tricker.setTopTrick("Backflip");
System.out.println(tricker);
}
output -:
DOG DATA
none is a none, a none dog.
The top trick is : Backflip.
The Corgi is 1 years old and weighs 15 pounds.
Sorry everyone. My code wasn't the problem. I tried using the code in a different compiler and it worked just fine. I did tweak my code a little with Kalana's advice. Thanks everyone.

Referencing a non static array list in a static environment?

I've just started to learn Java a month or so ago, and now have a problem with "non-static variable studentList cannot be referenced from a static context". I'm trying to have a separate method from main to populate the list of students, instead of copy pasting stuff from addStudent for each student; but I cannot get the methods to write to the ArrayList. (Error:(14, 27) java: non-static variable studentList cannot be referenced from a static context). I understand how the array is not static because it has an undefined size, but how could I make it work as is? Is there any better approach? Could I have the array be part of the main method and then have it passed on to addStudent, if so how?
import java.util.ArrayList;
public class Main {
ArrayList<Student> studentList = new ArrayList<>();
public static void main(String []args) {
addStudent("Adam", "Goldsmith", 70, 50);
addStudent("John", "Smith", 20, 40);
addStudent("Lewis", "Peterson", 90, 85);
for (Student obj: studentList){
System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
}
}
public static void addStudent(String forename, String surname, int coursework, int test) {
Student newStudent = new Student(forename, surname);
newStudent.setForename(forename);
newStudent.setSurname(surname);
newStudent.averageMark(70, 65);
studentList.add(newStudent);
}
}
and my "Student" Class:
public class Student {
String studentForename;
String studentSurname;
public Student(String studentForename, String studentSurname) {
setForename(studentForename);
setSurname(studentSurname);
}
// Set forename.
public void setForename(String newForename) {studentForename = newForename;}
// Set surname.
public void setSurname(String newSurname) {studentSurname = newSurname;}
//
public double averageMark(int courseworkMark, int testMark){
return (courseworkMark+testMark)/2;
}
// Grab the forename
public String grabForename(){
return studentForename;
}
// Grab the surname
public String grabSurname(){
return studentSurname;
}
// Grab the full name
public String grabFullName(){
return studentForename + "" + studentSurname;
}
}
Your code should look like this, especially your Student class using java encapsulation
public class Student {
private String studentForename;
private String studentSurname;
private int courseworkMark;
private int testMark;
public Student(String studentForename, String studentSurname, int courseworkMark, int testMark) {
this.studentForename = studentForename;
this.studentSurname = studentSurname;
this.courseworkMark = courseworkMark;
this.testMark = testMark;
}
public void setStudentForename(String studentForename) {
this.studentForename = studentForename;
}
public String getStudentSurname() {
return studentSurname;
}
public void setStudentSurname(String studentSurname) {
this.studentSurname = studentSurname;
}
public String getStudentForename() {
return studentForename;
}
public double averageMark(){
return (this.courseworkMark + this.testMark)/2;
}
public String grabFullName(){
return studentForename + " " + studentSurname;
}
}
And then testing via your Main class :
public class Main {
public static void main(String []args) {
ArrayList<Student> studentList = new ArrayList<>();
studentList.add(new Student("Adam", "Goldsmith", 70, 50));
studentList.add(new Student("John", "Smith", 20, 40));
studentList.add(new Student("Lewis", "Peterson", 90, 85));
for (Student obj: studentList){
System.out.println("Name: " + obj.getStudentForename() + " "+ obj.getStudentSurname());
}
}
}
import java.util.ArrayList;
public class Main {
static ArrayList<Student> studentList = new ArrayList<>();
public static void main(String []args) {
addStudent("Adam", "Goldsmith", 70, 50);
addStudent("John", "Smith", 20, 40);
addStudent("Lewis", "Peterson", 90, 85);
for (Student obj: studentList){
System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
}
}
public static void addStudent(String forename, String surname, int coursework, int test) {
Student newStudent = new Student(forename, surname);
newStudent.setForename(forename);
newStudent.setSurname(surname);
newStudent.averageMark(70, 65);
studentList.add(newStudent);
}
}
It was not due to undefined size but was because you were trying to access it without creating an object from a static method.
So just write static before it and it will work.
thought the above answer answers you question, but few words about static vs non static modifiyers in java
Characteristics of Static methods
A static method is called using the class (className.methodName) as opposed to to an instance reference (new instanceOfClass = class; instanceOfClass.methodName.)
Static methods can’t use non-static instance variables: a static method can’t refer to any instance variables of the class. The static method doesn’t know which instance’s variable value to use.
Static methods can’t call non-static methods: non-static methods usually use instance variable state to affect their behaviour. Static methods can’t see instance variable state, so if you try to call a non-static method from a static method the compiler will complaint regardless if the non-static method uses an instance variable or not.
Non-Static methods
A non-static method does not have the keyword static before the name of the method.
A non-static method belongs to an object of the class and you have to create an instance of the class to access it.
Non-static methods can access any static method and any static variable without creating an instance of the class.
So you'd better think if you need to define studentList as static or no, and if modify your code accordingly.
P.S. above written is taken from here
The difference between static (global, class level) and non-static (a instance of that class, an object) is important.
Creating an object by new Main() allows to work on that object and its fields.
The static void main(String[]) is the single entry point to the application.
Inside the main you have access only to static fields and static methods. So that is cumbersome.
package srivastava.arpit; // In a directory path srivastava/arpit/
import java.util.ArrayList;
public class Main {
private ArrayList studentList = new ArrayList<>();
public static void main(String []args) {
Main main = new Main();
main.execute();
}
private void execute() {
addStudent("Adam", "Goldsmith", 70, 50);
addStudent("John", "Smith", 20, 40);
addStudent("Lewis", "Peterson", 90, 85);
for (Student obj: studentList){
System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
}
}
public void addStudent(String forename, String surname, int coursework, int test) {
Student newStudent = new Student(forename, surname);
newStudent.setForename(forename);
newStudent.setSurname(surname);
newStudent.averageMark(70, 65);
studentList.add(newStudent);
}
}

Java: Array of Objects overwritten by last element [duplicate]

I have the following code:
public static void main(String[] args) {
Player players[] = new Player[2];
Scanner kb = new Scanner(System.in);
System.out.println("Enter Player 1's name");
players[0] = new Player(kb.nextLine());
System.out.println("Enter Player 2's name");
players[1] = new Player(kb.nextLine());
System.out.println("Welcome "+ players[0].getName() + " and " + players[1].getName());
}
It is meant to create a new player object and store the name of the player, while keeping all the objects in the array.
Here is the player class:
public class Player {
static String name;
public Player(String playerName) {
name = playerName;
}
public String getName(){
return name;
}
}
What actually happens is that it works when I just have 1 object, but when I have 2, each element in the array is the same as the second. When I have 3 objects in the array, each element is the same as the 3rd, etc.
I'm not sure why this is happening, or how to correct it, and it's been baffling me for hours :/
Its because of the static field. Statics are used across object instances. They are stored at class level.
Below code would work:
class Player
{
String name;
public Player(String playerName)
{
name = playerName;
}
public String getName()
{
return name;
}
}
Change static string name to private string name
Name field should not be static. Static means that the variable is actually global and shared across all class instances.
With the keyword static you have made name a class variable which is NOT an instance variable. A class variable is common to all the objects. Click for some more reading.

Instantiating and Updating Several Objects

Currently I am teaching myself Java but I came across a simple problem but have no one to ask from. From one of the exercises, I wrote a class and write a driver class that instantiates and updates several objects. I am confused by "instantiates and updates several objects." Here is what I mean: So here is my class:
public class PP43Car {
private String make = "";
private String model = "";
private int year;
public PP43Car(String ma, String m, int y)
{
make = ma;
model = m;
year = y;
}
public void setMake(String ma)
{
make = ma;
}
public String getMake()
{
return make;
}
public void setModel(String m)
{
model = m;
}
public String getModel()
{
return model;
}
public void setYear(int y)
{
year = y;
}
public int getYear()
{
return year;
}
public String toString()
{
String result = "Make of the vehicle: " + make +
" Model of the vehicle " + model +
" Year of the vehicle: " + year;
return result;
}
}
Which instantiates make, model and year. Then once I was writing the driver class, the way I began was:
import java.util.Scanner;
public class PP43CarTest {
public static void main(String[] args) {
PP43Car car1;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the model of the vehicle:");
car1.getModel();
}
}
But this class produces error and here is where I am stuck. Do I keep on going with this or is this what is meant by "instantiating and updating several objects?"
import java.util.Scanner;
public class PP43CarTest {
static PP43Car car1;
public static void main(String[] args) {
//Scanner scan = new Scanner(System.in);
car1 = new PP43Car("Millenia", "Mazda", 2011);
}
}
If the above code is correct, then can anyone show me how I can use the Scanner class to actually get the user input and update it that way because I would like to learn that as well?
Well, in your last fragment of code you are indeed instantiating an object, since you are doing:
car1 = new PP43Car("Millenia", "Mazda", 2011);
When you create a new object, you are creating a new instance of the class, so yes, you are instantiaing an object.
But you aren't updating it anywhere, because I think here updating means modifying the object, but you only create the object, not modify it...
Something like this would be an update:
car1.setYear(2013);
Since you are setting a different value for an attribute of the object, you are updating it...
EDIT: Try this code, it can't throw any exception, it's Java basics! I hope it clarifies your doubts...
public class PP43CarTest {
public static void main(String[] args) {
//Declaring objects
PP43Car car1;
PP43Car car2;
PP43Car car3;
//Instantiating objects
car1 = new PP43Car("Millenia", "Mazda", 2011);
car2 = new PP43Car("Aaaa", "Bbb", 2012);
car3 = new PP43Car("Ccc", "Ddd", 2012);
//Updating objects
car1.setMake("Xxx");
car1.setMake("Yyy");
car1.setYear(2013);
//Printing objects
System.out.println("CAR 1: " + car1.toString());
System.out.println("CAR 2: " + car2.toString());
System.out.println("CAR 3: " + car3.toString());
}
}

Categories