Extended class issues - java

I have had some issues involving code that accesess variables defined in a superclass that were later revised in a child class. Ie
//start of Stat class. Variables in question are defined here. (Name, Level, Experience, totalXP)
public class Stat {
public static String Name = " ";
public static int Level = 0;
public static double Experience = 0;
public static double totalXP = 0;
//Sets Name
public static void setName(String NameIn) {
Name = NameIn;
}
//Sets Level
public static void setLevel(int LevelIn) {
Level = LevelIn;
}
//Sets Experience
public static void setExperience(double ExperienceIn) {
Experience = ExperienceIn;
}
//Sets totalXP
public static void settotalXP(double totalXPIn) {
totalXP = totalXPIn;
}
//Sets up Attributes
public static void setall() {
setName("Herp");
setLevel(1);
setExperience(0);
settotalXP(0);
}
//Displays a Stat's Attributes
public static void DisplayLevel() {
System.out.println(Name);
System.out.println("Level: " + Level);
System.out.println(Experience + " out of " + totalXP + " total experience.");
}//End of method
public static void Levelup() {
if(Experience >= totalXP) {
Level++;
totalXP = totalXP * 1.3;
Experience = 0;
}//end of if statement
}//end of Levelup method
}//end of Stat.class
public class Agility extends Stat{
{//Revisionary Block
Name = "Agility";
Level = 1;
Experience = 0;
totalXP = 125;
}
public static int runnappDodge(int Dodge) {
Random generator = new Random(10);
Dodge = generator.nextInt(10);
if (Dodge == 0) {
Player.incomingDMG = 0;
}//end of if statement
return Dodge;
}
//start of the method located on player.class. This prints out " ", 0.0 and 0.0 for all //of the fields.
public static void checkLevel() {
System.out.println("You are level: " + Level);
System.out.println("You have " + experience + " experience out of " + totalXP + " total experience");
System.out.println(stat.Attack.Name + " Level: " + stat.Attack.Level + ": Experience: " + stat.Attack.Experience + "/" + stat.Attack.totalXP);
System.out.println(stat.Archery.Name +" Level: " + stat.Archery.Level +": Experience: " + stat.Archery.Experience + "/" + stat.Archery.totalXP);
System.out.println(stat.Agility.Name +" Level: " + stat.Agility.Level + ": Experience: " + stat.Agility.Experience + "/" + stat.Agility.totalXP);
}//end of checkLevel method
my full code is here: http://pastebin.com/6nPGwJQe
reddit was no help so I now turn to you. (not that you arent helpful, but I just use reddit more so it is more convenient). I think that my code should be updating the variables in the subclasses but it doesnt. When I refrence the variable it ends up being excactly what it was when defined by super class, in Aaron.name's case, " " rather than "Aaron". I'm not sure if a getter and setter might be useful here, but I appreciate all advice
PS: My first question on stackoverflow!
Edit: Thanks for the feedback. This was example code. The last commenter helped out a lot, but my real code is entirely independent from this. It was to convey an example. So please see the link because that code is really what matters.
Edit 2: Because I can see that one might need to see the structure of my project for imports and references sake, here is an image of my project structure: http://imgur.com/VhDzRrm
Edit 3: No longer does my post use an example that is incorrect, it uses my actual code.

Java is very clear about case-sensitivity. Since you have extended the Derp class your Aaron class now has two String fields. name and Name. That is why it is displaying nothing, because you have instantiated your name String to "". if you replaced it with Aaron.Name you will have what you are looking for.

I'll go over a few issues in your code.
First obviously, it doesn't compile, as others have pointed out. You should take your actual code and strip out anything that's not germane to the problem. Keep stripping until your sample code is as small as what you posted here, but make sure it still compiles. See http://sscce.org/
Odds are, you'll find the bug as you go, in which case post your own answer to the question (yes, you can do that). If not, edit your question with the actual code.
Now, to address your issues:
There was no need to use an anonymous constructor for Aaron. It should have been
public class Aaron extends Derp {
public Aaron() { Name = "Aaron"; IQ = 10; }
}
(Something tells me you're coming from a C++ background.)
"name" is an instance variable, which means that it only exists as part of an object of type Derp (or Aaron). You first need to create an object, then reference that.
public static void main() {
Aaron aaron = new Aaron();
System.out.println("Hi, my name is: " + aaron.name + "!\n");
}
You could also have made name a class variable:
static String name = " ";
but there's no good way to override that variable in a subclass, so we won't go there.
One final nit: you didn't need that "\n" in the println() call, since that function appends a newline for you.

Related

Java code issue [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm having an issue with my code. It won't compile and every time I try to fix it I get an error. I can't see what the problem with it is. I may be just overlooking or looking too hard. I haven't done Java coding since 2006 until I took this class. The class doesn't go a lot into the coding and I'm trying to work off of my memory. I have been working on this code and looking at this code since I wrote it over a week ago. Can someone look and tell me what I screwed up. It's already past-due. I already showed the teacher but haven't got any help and my school doesn't currently have a tutor for this class during this semester. Please help! Code and errors are below:
Errors:
/*
* File: Guitar2.java
* Author: Eppards,Michael
* Date: June 11, 2018
*/
class Guitar2 {
private int numStrings;
private double guitarLength;
private Color guitarColor;
private Manufacturer guitarManufacturer;
enum Manufacturer {
GIBSON,
FENDER,
IBANEZ;
}
enum Color {
RED,
BLUE,
BLACK;
}
// Default Constructor
private Guitar2() {
this.numStrings = 6;
this.guitarLength = 28.2;
this.guitarColor = Color.RED;
this.guitarManufacturer = Manufacturer.GIBSON;
}
// Argument Constructor
private Guitar2(int numStrings, double guitarLength, Color guitarColor, Manufacturer guitarMaker) {
this.numStrings = numStrings;
this.guitarLength = guitarLength;
this.guitarColor = guitarColor;
this.guitarManufacturer = guitarMaker;
}
// Getters
public int getNumStrings() {
return numStrings;
}
public double getGuitarLength() {
return guitarLength;
}
public Color getGuitarColor() {
return guitarColor;
}
public Manufacturer getGuitarManufacturer() {
return guitarManufacturer;
}
// playGuitar method for 16 randomly selected musical notes
enum Notes {
A(1),
B(4),
C(1),
D(2),
E(0.25),
F(0.5),
G(0.5);
double duration;
private Notes(double duration) {
this.duration = duration;
}
}
public String playGuitar() {
String play = "[";
int a;
int b;
// initiate a random number
Random rn = new Random();
// for loop to select random notes
for (int k = 0; k < 16; k++) {
a = rn.nextInt(7);
b = rn.nextInt(5);
play = play + Notes.values()[a] + "(" + Notes.values()[a].duration + ")";
if (k != 15) play = play + ",";
}
play = play + ']';
return play;
}
// used to return the info in a string
public String toString() {
String infoString = "(numStrings=" + this.numStrings + ", guitarLength=" + this.guitarLength + ",guitarManufacturer=" + this.guitarManufacturer + ",guitarColor=" + (this.guitarColor == null ? "none" : this.guitarColor.name()) + ")";
return infoString;
}
}
Guitar2.java:80: error: cannot find symbol
Random rn = new Random();
^
symbol: class Random
location: class Guitar2
Guitar2.java:80: error: cannot find symbol
Random rn = new Random();
^
symbol: class Random
location: class Guitar2
2 errors
-Hello, World!-
There were quite a few issues with the code that caused it to not compile. I fixed all of them (I think) and have written out what was wrong:
Public needs to be changed to public
The second Guitar constructor is missing all it's parameters.
Enums need to be referenced by their name, you can't just type in their values.
Your curly braces were all over the place. There were way more closing than opening, so I deleted a bunch of them at the end and ones that were tossed into the middle of the class.
Methods must be within classes.
Enums can't be declared inside methods, only inside classes.
Variable declarations must have a space between the type and the name of the variable. Example: int_a; needs to be int a;
Your Duration enum has no constructor that accepts and int.
Getting a random value of an enum based on its index is done by doing Notes.values()[a];, not Notes[a];
No idea where the return Optional.empty(); line should be, so I deleted it.
You're missing the import for the Random class.
Strings can't be on multiple lines.
.orElse() is not a method. Deleted this, unsure what it was supposed to do.
colorName() is not a method. I changed it to: (this.guitarColor == null ? "none" : this.guitarColor.name()).
The name of the variable in the toString() method is not the same as what you try to return. I changed them both to infoString.
You have a TON of typos, namely with things like Manufacturer being Manufacur and return being rturn.
When initializing a variable, you must have a space after new.
Your getter methods do not return the correct type.
The name of the variable numString is repeatedly referred to as numStrings. I added the s to the original variable declaration.
Below are a list of things you really SHOULD change, but you don't need to change.
All enum names should be in ALL CAPS.
Method names should be written using camelCase. Example: myVal would have a getter named getMyVal().
Have blank lines between methods, constructors, and types.
Have a space after the start of a comment. Example: // Comment Bad Example: //Comment
Have some sort of sorting pattern for enums. For notes, it should be alphabetical.
There is no need to have another enum for the duration of notes. This can easily be done in the note itself.
There is no need to do String.valueOf(someObject) for concatenation. It is better to do someObject.toString() and best to just leave it as someObject because the runtime will do that operation for you.
There should be a space before and after arithmetic operators like + and -.
I would highly recommend you read up on some basic Java tutorials and look at the Google Java Style Guide. It is what I use and what I'm sure a lot of people use to determine how code should look.
With all the changes and with the proper use of style, your code looks like this:
import java.util.Random;
/*
* File: Guitar.java
* Author: Eppards,Michael
* Date: June 11, 2018
*/
class Guitar {
private int numStrings;
private double guitarLength;
private Color guitarColor;
private Manufacturer guitarManufacturer;
enum Manufacturer {
GIBSON,
FENDER,
IBANEZ;
}
enum Color {
RED,
BLUE,
BLACK;
}
enum Notes {
A(1),
B(4),
C(1),
D(2),
E(0.25),
F(0.5),
G(0.5);
double duration;
private Notes(double duration) {
this.duration = duration;
}
}
// Default Constructor
private Guitar() {
this.numStrings = 6;
this.guitarLength = 28.2;
this.guitarColor = Color.RED;
this.guitarManufacturer = Manufacturer.GIBSON;
}
// Argument Constructor
private Guitar(int numStrings, double guitarLength, Color guitarColor, Manufacturer guitarMaker) {
this.numStrings = numStrings;
this.guitarLength = guitarLength;
this.guitarColor = guitarColor;
this.guitarManufacturer = guitarMaker;
}
// Getters
public int getNumStrings() {
return numStrings;
}
public double getGuitarLength() {
return guitarLength;
}
public Color getGuitarColor() {
return guitarColor;
}
public Manufacturer getGuitarManufacturer() {
return guitarManufacturer;
}
// playGuitar method for 16 randomly selected musical notes
public String playGuitar() {
String play = "[";
int a;
int b;
// initiate a random number
Random rn = new Random();
// for loop to select random notes
for (int k = 0; k < 16; k++) {
a = rn.nextInt(7);
b = rn.nextInt(5);
play = play + Notes.values()[a] + "(" + Notes.values()[a].duration + ")";
if (k != 15) play = play + ",";
}
play = play + ']';
return play;
}
// used to return the info in a string
public String toString() {
String infoString = "(numStrings=" + this.numStrings + ", guitarLength=" + this.guitarLength + ",guitarManufacturer=" + this.guitarManufacturer + ",guitarColor=" + (this.guitarColor == null ? "none" : this.guitarColor.name()) + ")";
return infoString;
}
}
Hope this helps! Friendly reminder that I made a LOT of changes to this code. You really should go look at the steps I took and make the changes yourself, otherwise you could get in trouble with your school for submitting work that is not your own.

Java 8: No errors - Why is this for loop running forever and not showing anything?

My issue is with the following code. Eclipse IDE gives me no errors or warnings, yet when I print out a simple System.out.println("Test" + i);, I would get a running program up to the number 2509, or currently 2517 after rebooting Eclipse.
Essentially, I want to take an array of objects, say an array of "persons," and place them in random spots in another object array, say "bus stops." Assume that I have properly made the object arrays for "busStops and "people"
Yes, I realize that it defeats the purpose of making the "person" object as of yet, but that is something that can be included later.
Edit: Null values are simulated areas where people can't go, like a lake.
Edit2: replaced for with while loop, replaced decremented i with continue keyword.
Edit3: added more of the methods to elaborate the imperfections of my code. Then again, maybe most of it is good and I'm not understanding something important about loops.
private static void distributePeople() {
boolean temp = true;
int i = 0;
while (temp) {
// Select random points in array
int a = rand.nextInt(busStops.length);
int b = rand.nextInt(busStops[0].length);
// At random busStop, check if available and check if not full.
// If it is not full, place a person there.
if (busStops[a][b] == null) {
// if null, reset this run
continue;
} else {
if (busStops[a][b].isMaxPeople() == false) {
busStops[a][b].setNumberOfPeople(1);
i++;
System.out.println("Test: " + i);
} else {
// if true, reset this run
continue;
}
}
if (i == people.length) {
temp = false;
}
}
}
private static void setMaxPeopleAtBusStop() {
busStops[0][0].setMaxNumberOfPeople(1977 + 2);
busStops[1][0].setMaxNumberOfPeople(2 + 1643);
busStops[2][0].setMaxNumberOfPeople(1643 + 1201);
busStops[3][0].setMaxNumberOfPeople(1201 + 1267);
busStops[0][1].setMaxNumberOfPeople(366 + 0);
busStops[2][1].setMaxNumberOfPeople(0 + 797);
busStops[3][1].setMaxNumberOfPeople(797 + 34);
busStops[0][2].setMaxNumberOfPeople(1740 + 0);
busStops[2][2].setMaxNumberOfPeople(0 + 1444);
busStops[3][2].setMaxNumberOfPeople(1444 + 1963);
busStops[0][3].setMaxNumberOfPeople(839 + 1131);
busStops[1][3].setMaxNumberOfPeople(1131 + 1092);
busStops[2][3].setMaxNumberOfPeople(1092 + 912);
busStops[3][3].setMaxNumberOfPeople(912 + 1965);
busStops[0][4].setMaxNumberOfPeople(1552 + 1297);
busStops[1][4].setMaxNumberOfPeople(1297 + 1345);
busStops[2][4].setMaxNumberOfPeople(1345 + 614);
busStops[3][4].setMaxNumberOfPeople(614 + 1108);
busStops[0][5].setMaxNumberOfPeople(1490 + 228);
busStops[1][5].setMaxNumberOfPeople(228 + 187);
busStops[2][5].setMaxNumberOfPeople(187 + 906);
busStops[3][5].setMaxNumberOfPeople(906 + 36);
busStops[0][6].setMaxNumberOfPeople(634 + 1293);
busStops[1][6].setMaxNumberOfPeople(1293 + 0);
busStops[3][6].setMaxNumberOfPeople(0 + 1929);
busStops[0][7].setMaxNumberOfPeople(759 + 388);
busStops[1][7].setMaxNumberOfPeople(388 + 0);
busStops[3][7].setMaxNumberOfPeople(0 + 1149);
busStops[0][8].setMaxNumberOfPeople(1809 + 1880);
busStops[1][8].setMaxNumberOfPeople(1880 + 1979);
busStops[2][8].setMaxNumberOfPeople(1979 + 954);
busStops[3][8].setMaxNumberOfPeople(954 + 1332);
busStops[0][9].setMaxNumberOfPeople(1890 + 408);
busStops[1][9].setMaxNumberOfPeople(408 + 1771);
busStops[2][9].setMaxNumberOfPeople(1771 + 587);
busStops[3][9].setMaxNumberOfPeople(557 + 1961);
}
From the appropriate BusStop class:
static int MAX_PEOPLE_HERE;
public int setNumberOfPeople(int a) {
return numberOfPeopleHere += a;
}
protected boolean isMaxPeople() {
if (numberOfPeopleHere >= MAX_PEOPLE_HERE) {
return true;
} else {
return false;
}
}
public void setMaxNumberOfPeople(int a) {
MAX_PEOPLE_HERE = a;
}
Note: I should have a max number of 13000 people, which is smaller than the room available above.
Ok so your problem is that you're using a static variable for MAX_PEOPLE_HERE but you're trying to use it in a non static way. Thus ever time you call setMaxNumberOfPeople on any bus stop you set it for all bus stops.
This means that MAX_PEOPLE_HERE will end up being 557 + 1961 = 2518.
I'm guessing that numberOfPeopleHere is also static and thus you can only ever 2518 people to bus stops. If you try to do more than this then you'll end up with an infinite loop as you are seeing.
Change both MAX_PEOPLE_HERE (rename this to maxPeopleHere) and numberOfPeopleHere to local instance variables and I suspect everything will start working.
Use continue instead of i-- to skip current iteration. As #Hovercraft Full Of Eels stated, you've got infinite loop because of index modification within the loop

How to update a variable first and then execute the rest of the code in java

I'm learning app development for Android and have a small problem with my code. In the google tutorial i am working with we created a coffe ordering app. I did some extra coding for my plus and minus buttons, because i wanted them to update the price while changing the amount of cups ordered. That worked great, the moment i press the button the amount of cups and the total price get updated at the same time.
Now here comes my problem. I wanted to output a string with "Total: " + totalPrice, but that doesn't work and i found out why.
public void addCups(View view) {
numberOfCups = numberOfCups + 1;
display(numberOfCups);
displayMessage(gBetrag + endPreis);
}
Here are my global variables:
int numberOfCups = 0;
int priceOfCup = 5;
String message = "Vielen Dank!";
String gBetrag = "Gesamt: ";
String endPreis = NumberFormat.getCurrencyInstance().format(numberOfCups * priceOfCup);
I ran the code in debugging mode and found out that the method first looks for whats in "gBetrag" and "endPreis" before it updates the "numberOfCups" variable.
The output is "Gesamt: 0.00€" because endPreis is calculated before numberOfCups gets a +1. How do get java to execute the code in the order it was written or rather read the variable after it was updated?
I can workaround this issue if add the variable to every method i want to use it in, but that just adds more code and i tought that's why you use global variables.
You need to calculate the endPreis each time a cup is added:
public void addCups(View view) {
numberOfCups = numberOfCups + 1;
calculateTotal();
display(numberOfCups);
displayMessage(gBetrag + endPreis);
}
private void calculateTotal() {
endPreis = NumberFormat.getCurrencyInstance().format(numberOfCups * priceOfCup);
}
I suppose your class is written this way :
public class MyClass {
int numberOfCups = 0;
int priceOfCup = 5;
String message = "Vielen Dank!";
String gBetrag = "Gesamt: ";
String endPreis = NumberFormat.getCurrencyInstance().format(numberOfCups * priceOfCup);
public void addCups(View view) {
numberOfCups = numberOfCups + 1;
display(numberOfCups);
displayMessage(gBetrag + endPreis);
}
}
So here is how your code will be executed :
numberOfCups is set to 0
priceOfCup is set to 5
message is set
gBetrag is set
endPreis is set to (numberOfCups * priceOfCup)
When you call addCups(), it will display endPreis value.
As you could see, endPreis value was never re-calculated ;)

Can't remember how to do this for some reason

This one should be fairly simple I think, I just can't remember how, when using get methods of an object, how to pull the highest double out of the pack and put it in the println.
So far I just get every object to print with its percentages. But for the life of me I just can't remember and I know I've done this before.
public void displayBookWithBiggestPercentageMarkup(){
Collection<Book> books = getCollectionOfItems();
Iterator<Book> it = books.iterator();
while(it.hasNext()){
Book b = it.next();
double percent = b.getSuggestedRetailPriceDollars() / b.getManufacturingPriceDollars() * 100.0;
System.out.println("Highest markup is " + percent + " " + b.getTitle() + " " + b.getAuthor().getName().getLastName());
}
}
I'm pretty sure I need another local variable but I can't seem to do anything but make it equal the other percent. I have removed the other variable for now as I try to think about it.
I won't go into a lot of detail because it's homework (well done for being up-front about that, by the way) but here's the key idea: keep track of the largest percentage you've seen so far as your loop runs. That's what you want in your other variable.
Good job posting what you've tried so far. You were on the right track. As you loop through your books, keep a variables continuously updated with the highest percent seen so far and another variable for the associated book. Output the variable at the end outside the loop after iteration is done. Also, don't forget to check the edge case of an empty list of books! Something like this should do the trick:
public void displayBookWithBiggestPercentageMarkup(){
Collection<Book> books = getCollectionOfItems();
if (books.size() == 0) {
return;
}
Iterator<Book> it = books.iterator();
double highestPercent = 0;
Book highestPercentBook = null;
while(it.hasNext()){
Book b = it.next();
double percent = b.getSuggestedRetailPriceDollars() / b.getManufacturingPriceDollars() * 100.0;
if (percent > highestPercent) {
highestPercent = percent;
highestPercentBook = b;
}
}
System.out.println("Highest markup is " + highestPercent
+ " " + highestPercentBook.getTitle()
+ " " + highestPercentBook.getAuthor().getName().getLastName());
}

Java enum ordinal returning -1?

Alright so I'm currently writing some code for a project I'm working on, and I decided an Enum for data storage will be my best bet. But in the first time in my life, the enum.ordinal() returns -1?
Heres the code:
DuelRules.Rules rule = DuelRules.Rules.values()[(buttonId - (buttonId < 29 ? 18 : 19))];
if (buttonId == 29) {
rule = DuelRules.Rules.POCKET;
}
System.out.println(rule + ", " + rule.ordinal());
rules.swapRule(player, other, rule);
reset(false);
This statement here:
System.out.println(rule + ", " + rule.ordinal());
It prints the correct rule value, but when it prints rule.ordinal() it is printing -1?
Example:
HAT, -1
My Enum:
public enum Rules {
HAT(5000, 1),
CAPE(5000, 2),
AMULET(5000, 4),
WEAPON(5000, 8),
BODY(5000, 16),
SHIELD(5000, 32),
LEG(5000, 128),
GLOVE(5000, 512),
BOOT(5000, 1024),
RING(5000, 4096),
ARROW(5000, 8192),
POCKET(17837, 1),
FORFEIT(4989),
MOVEMENT(4990),
RANGE(4991),
MELEE(4992),
MAGIC(4993),
DRINKS(4994),
FOOD(4995),
PRAYER(4996),
OBSTACLES(4997),
FUN_WEAPONS(4998),
NO_ABILITIES(4999),
SUMMONING(5001);
private final int varbitId;
private final int value;
private Rules(int id, int... value) {
this.varbitId = id;
this.value = value.length > 0 ? value[0] : 0;
}
}
Note, that enum is inside of another class, not sure if that can effect the outcome. Thanks for your help, I'm completely lost with this one.
EDIT: Upon farther review I found that the ordinal is being changed by passing it as an argument?
Screnshot of console:
Code:
} else if (buttonId >= 18 && buttonId <= 42) {
DuelRules.Rules rule = DuelRules.Rules.values()[(buttonId - (buttonId < 29 ? 18 : 19))];
System.out.println("Point one: "+rule + ", " + rule.ordinal());
rules.swapRule(player, other, rule);
getDuel(other).rules.setRules(player, other, rules
.rules);
reset(false);
sendFlash(interfaceId, buttonId);
}
Where it prints Point one, the Rule and its .ordinal is correct, in this case OBSTACLES, 20
But where it passes the rule paramters in rules.swapRule, it changes the ordinal to -1?
public boolean swapRule(Player player, Player other, Rules rule) {
System.out.println("Point 2(swapRule): " + rule + ", " + rule.ordinal());
}
What is causing the Rule parameters to be changes when getting passed as an argument?
Your approah defeats the sheer purpose of using an enumerator. Instead of mangling with indices you could use the Enum directly like this
button.setActionCommand (Rules.HAT.toString ());
Then in your ActoinListener you can determine which button was clicked by using this
public void actionPerformed (ActionEvent e) {
if (Rule.valueOf (e.getActionCommand()) == Rules.HAT) {
//HAT related button was called, process it
}
}
You can get this result by reflection:
import java.lang.reflect.Field;
public class Main {
enum Fruit { APPLE }
public static void main(String[] args) {
try {
Field field = Fruit.class.getSuperclass().getDeclaredField("ordinal");
field.setAccessible(true);
field.set(Fruit.APPLE, -1);
} catch (Exception e) {
}
System.out.println(Fruit.APPLE + ", " + Fruit.APPLE.ordinal());
}
}
However I doubt anyone could do this by mistake.

Categories