So, I'm creating a text based game in Java and the currency is jellybeans. I have an issue, though. Whenever I set the currency to add 5, it doesn't, and returns 0. Here's the code
public class Util{
public int Jellybeans = 0;
public void jellybeans(int Amount){
Jellybeans = Jellybeans + Amount;
}
public int getJellybeans(){
return Jellybeans;
}
}
public class Tutorial{
Util util = new Util();
private int jellybeanCount = util.getJellybeans();
private void dialog(){
//unrelated irrelevant stuff
util.jellybeans(5);
Util.printAnimatedText("You now have " + jellybeanCount + "
jellybeans!")'
}
}
Any help would be greatly appreciated, this is probably a basic issue but I'm not sure
You're invoking the getJellybeans() in the wrong place. What you need to do is:
Util util = new Util();
private int jellybeanCount;
private void dialog(){
util.jellybeans(5);
jellybeanCount = util.getJellybeans(); // here
Util.printAnimatedText("You now have " + jellybeanCount + "
jellybeans!")'
}
Why is that?
Because when you create the Util object at the beginning, the Jellybeans field is yet empty (or particularly equals ZERO). So when you invoke the getJellybeans(), the field is still has no 5 yet and returns its initial value ZERO.
But the after setting the value of the field to 5 util.jellybeans(5);, you then HAVE a field with a value in it other than zero. You can get now.
Edit
If you really want to have a jellybean counter, and encapsulate it, you should do a few extra things:
public class Util{
private int Jellybeans = 0; //make this variable private, so you only expose it and edit it via getters and setters
public void jellybeans(int Amount){
Jellybeans = Jellybeans + Amount;
}
public int getJellybeans(){
return Jellybeans;
}
}
Util util = new Util();
//private int jellybeanCount = util.getJellybeans(); // this is not needed
private void dialog(){
//unrelated irrelevant stuff
util.jellybeans(5);
Util.printAnimatedText("You now have " + util.getJellybeans() + "
jellybeans!")' // here you use the getter, so you have full control of the state of util class
}
this way, you encapsulate the behavior of your object inside the Util class, that's way you have a class, with an instance variable in the first place.
You are not calling the getJellybeans() methods after calling jellybeans(5).
private int jellybeanCount = util.getJellybeans();
private void dialog(){
//unrelated irrelevant stuff
util.jellybeans(5);
jellybeanCount = util.getJellybeans();
Util.printAnimatedText("You now have " + jellybeanCount +
jellybeans!")'
}
Since int is primitive type and not set by reference in
private int jellybeanCount= ...
you might want to modify this method below to return a value
public int jellybeans(int Amount){
return Jellybeans + Amount;
}
And invoke it as below
jellybeanCount = util.jellybeans(5);
Util.printAnimatedText("You now have " + jellybeanCount + "
jellybeans!")'
Related
I would like a little help in java from you guys. My idea is to generate two integer variables from the random method and make it a constant string. Something like:
//In Class
Random rand = new Random();
protected int aux1 = rand.nextInt(9999), aux2 = rand.nextInt(10);
public final String x = aux1+"-"+aux2; //is it possible to take just one time?
public String getX() {return x;}
But each time when I use the getX() in main class I got different values for x: 9626-3 4938-0 6500-6
instead of: 4938-0 4938-0 4938-0
How can I do this?
grateful for the attention.
You got three different values ... because you ASKED for three different values.
It sounds like:
You want a string, consisting of two random integers and a dash.
The first integer is initialized once, the second always changes.
Potential solution:
public class MyClass {
protected Random rand = new Random();
protected int aux1 = rand.nextInt(9999)
public String makeIdentifier() {
int aux2 = rand.nextInt(10);
return aux1 + "-" + aux2;
}
...
In other words, you've:
refactored the "common code" into class members
isolated the "unique" code in it's own method
Update 1
As I asked yesterday, it would be helpful if you'd better explain what you're trying to do. NOT "how" you're trying to do it, but WHAT you're trying to accomplish. By showing some output samples.
Let's go back to your initial post:
If you just want a string (e.g. "identifier") , with two random numbers separated by a dash...
... and if you never want it to change over the lifetime of the object...
... then here's how you could do it:
public class MyClass {
protected Random rand = new Random();
protected String identifier =
rand.nextInt(9999) + "-" + rand.nextInt(10);
public String getIdentifier() { return identifier; }
}
...
Note that the member "identifier" is initialized ONCE, when the class is instantiated.
It sounds like that's what you were trying to do in your original post. But - since you didn't show a complete SSCCE, there's no way to tell exactly why it didn't work for you :(
Update 2
Thank you for your update. I can't overemphasize the value of a good SSCCE.
It's now clear that you have TWO classes. Each time you create a new instance of "Test2" ... you get a new value of "x". That's the part you don't like.
SOLUTION:
Don't call it "Test2". Make your class do one thing, and do it well. Let's say you want an "identifier string", like "XXXX-YY". Then call your class "Identifier". Or let's say you want "control information" like "identifier string" and "sequence number". Then call it "ControlInformation".
Let's say you want the SAME value, "XXXX-YY", no matter how many times you invoke the class, or how many instances you invoke it from. Then, as Oleg aready suggested, use static
EXAMPLE SOLUTION:
ControlInformation.java
import java.util.Random;
/**
* SAMPLE OUTPUT:
* Creating two object instances: c1 and c2...
* c1: 0, 1461-2
* c2: 0, 1461-2
* Incrementing c1..
* c1: 1, 1461-2
* c2: 0. 1461-2
*/
public class ControlInformation {
// "identifier" initialized exactly once; will be the same for all instances
protected static Random rand = new Random();
protected static String identifier =
rand.nextInt(9999) + "-" + rand.nextInt(10);
// "Sequence" will vary per object
protected int sequence = 0;
// Public access
public String getIdentifier() { return identifier; }
public int getSequence() { return sequence; }
public int increment() { return ++sequence; }
public static void main (String[] args) {
System.out.println("Creating two object instances: c1 and c2...");
ControlInformation c1 = new ControlInformation();
ControlInformation c2 = new ControlInformation();
System.out.println("c1: " + c1.getSequence() + ", " + c1.getIdentifier());
System.out.println("c2: " + c2.getSequence() + ", " + c2.getIdentifier());
System.out.println("Incrementing c1..");
c1.increment();
System.out.println("c1: " + c1.getSequence() + ", " + c1.getIdentifier());
System.out.println("c2: " + c2.getSequence() + ". " + c2.getIdentifier());
}
}
I have this (in class MyClass):
private static int sequence = 1;
protected String number;
private float limitValue;
Random rand = new Random();
public String x = rand.nextInt(9999)+"-"+rand.nextInt(10);
MyClass () { number = "0000" + sequence++; }
public void showData() {
System.out.printf(" Number: %s - X: %s - Limit value: %.2f.\n", getNumber(), getX(), limitValue);
}
in my main class:
MyClass y1 = new MyClass();
value = 500f;
y1.setLimitValue(value);
y1.showData();
MyClass y2 = new MyClass();
value = 700f;
y2.setLimitValue(value);
y2.showData();
MyClass y3 = new MyClass();
value = 900f;
y3.setLimitValue(value);
y3.showData();
and I got, for example, this output:
Number: 00001 - X: 3383-6 - Limit value: 500,00.
Number: 00002 - X: 2513-4 - Limit value: 700,00.
Number: 00003 - X: 8012-5 - Limit value: 900,00.
and my intention is get the same value of x for all y (y1, y2, y3).
I m currently trying to code a Calender with java.
I created 3 classes:
1. Date( includes year, month....)
2. Event(includes people, place, the class Date ... + an option to create dates )
3. Mainclass My mainclass that contains the menu.
My problem is that I don't know how the user is able to create his own date, because I have to create the object Termin myself... So, can somebody help me fix this? Thx in advance!
public class Event {
private String mDescription, mPlace, mNames;
private Date mStart, mEnd;
Termin(String description, String place, String names, Date start, Date end) {
mBetreff = description;
mOrt = place;
mNamen = names;
mBeginn = start;
mEnde = end;
}
public void create() {
Scanner read = new Scanner(System.in);
System.out.println("Enter 1. description 2. place 3. names 4. start 5. end ein");
mDescription = read.nextLine();
mPlace = read.nextLine();
mNames = read.nextLine();
}
public String toString() {
return "Description : " + mDescription + "\nPlace: " + mPlace + "\nNames: " + mNames + "\nIts starts at " + mStart
+ " and ends at " + mEnd;
}
}
public class Date {
private int year, day, month, hours, minutes;
Datum(int year, int month, int day, int hours, int minutes) {
this.day= day;
this.year= year;
this.month= month;
this.hours= hours;
this.minutes= minutes;
}
public String toString() {
return "\n" + day + "." + month + "." + year + " um " + hours+ ":" + minutes;
}
public void enterDate() {
}
}
EDIT:
I asked this question 2 years ago, back when I just started coding and had no idea of oop and encapsulation ...
To answer my own question, for every newbie that also tries to create a terminal calender:
Date needs the following methos:
public setDate() {
this.year = read.nextLine();
...
}
for every member.
Event takes the resulting object Date, either in the constructor or in a setter like method.
Creating an instance-method to create an appointment is kind of... strange since one needs to create an appointment (called Termin in your case) to create an appointment. One possibility would be the builder pattern. By having a public static inner builder class, you can set the constructor(s) private and enforce the use of that builder:
public class Main {
private int value;
private Main(int value) {
this.value = value;
}
public int getValue() {
return (this.value);
}
public static class MainBuilder {
boolean valueWasSet;
int value;
public MainBuilder() {
this.valueWasSet = false;
this.value = -1;
}
public void setValue(int value) {
this.value = value;
this.valueWasSet = true;
}
public Main build() {
if (!this.valueWasSet) {
throw new IllegalStateException("value must be set before a Main can be build.");
}
return (new Main(this.value));
}
}
}
(this is a simplified sketch to show the core mechanism on how to assert that certain values are set before constructing a Main through MainBuilder.
The process of constructing a Main would be:
MainBuilder builder = new MainBuilder();
builder.setValue(100);
// all following Main's will have a value of 100
Main mainOne = builder.build();
Main mainTwo = builder.build();
builder.setValue(200);
// all following Main's will have a value of 200
Main mainThree = builder.build();
Main mainFour = builder.build();
This question already has answers here:
Having inheritance and polymorphism issues with Java
(2 answers)
Closed 6 years ago.
I am trying to output calclatefee of $2 per day after 3 days. I have switched things around and I am left at this which looks a little sloppy. This Array is also making me take the confusing way.
public class Movie {
String rating;
String title;
int id;
int rentTime;
public String setrating() {
return rating;
}
public void rating(String getrating) {
rating = getrating;
}
public int setid() {
return id;
}
public void id(int agetid) {
id = agetid;
}
public String settitle() {
return title;
}
public void title(String gettitle) {
title = gettitle;
}
public int setfees() {
return rentTime;
}
public void fees(int getrentTime) {
rentTime = getrentTime;
}
public Movie() {
title = " ";
rating = " ";
id = 0;
rentTime = 0;
System.out.println("default constructor");
}
public Movie(String title, String rating, int id, int rentTime) {
title = " not overridden ";
rating = " NR ";
id = 0;
rentTime = 0;
System.out.println("Overloaded -" + title + rating + id + rentTime);
}
public static void main(String[] args) {
Movie[] Array = {
new Action(" The 100", " pg-13", 105, 7, 3),
new Comedy(" Supernatural", " pg-13", 5, 2, 0),
new Drama(" Lost 2", " R", 9, 2, 0) };
for (int x = 0; x < Array.length; x++) {
// System.out.println(x);
System.out.println(Array[x].toString());
}
}
}
public abstract class Action extends Movie {
protected double latecost;
protected double latefees = 3;
public Action(String gettitle, String getrating, int getid, int getrentTime, double latecost) {
super(gettitle, getrating, getid, getrentTime);
title = gettitle;
rating = getrating;
id = getid;
rentTime = getrentTime;
latecost = latefees;
System.out.println("Overridden " + title + rating + " " + id + " " + " " + rentTime + " "
+ latecost);
}
public double calclatefees(double latecost, double rentTime) {
if (rentTime > 3)
latefees = ((rentTime - 3) * latecost);
return latefees;
}
#Override
public String toString() {
String x = "\nMovie: " + title + " is rated " + rating + "\nMovie ID number: " + id
+ " and the late fee for action movies is $" + latecost + "\n";
return x;
}
protected void finalize() throws Throwable {
try {
System.out.println("Finalize method");
} finally {
super.finalize();
}
}
public void dispose() {
System.out.println(" dispose method");
}
}
Problems:
There's no calclatefee method to override in the parent class. If you want a child class to override method, it must be present in the parent class, at least as an abstract method (if the parent is abstract or is an interface).
You never call your calclatefee method anywhere, so you shouldn't expect to ever see its result in your output.
Your child class, Action, is abstract -- isn't that backwards? Most often its the parent class that's abstract, so why are you structuring it this way? And as written your main method shouldn't compile since you seem to be trying to create an instance of an abstract class.
Your class overrides the finalize() method, something that is generally not recommended. Fortunately your override doesn't really do anything other than output to the standard out and then call the super's method, but still, why risk it?
Side issues
Your code does not follow Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
You will want to try to improve the formatting of your code that you post in here and your code in general. Good formatting including using an indentation style that is uniform and consistent will help others (us!) to better understand your code, and more importantly, it will help you to better understand your code and thus fix your own bugs. Also it shows that you're willing to put in extra effort to make it easier for the volunteers here to help you, and that effort is much appreciated. I took the liberty of trying to fix this for you.
Hey there Stackoverflowers,
I just started programming in Java and encountered a strange problem concerning printing an object. When a new object of type gast is created the user has to enter his or her birthday. This al works fine, however, if I try to print it out I returns 0-0-0. Why is that? By the way, if I create a new datum directly with the parameter constructor it works fine. Wherein lays the problem? I just can't figure it out. I hope you guys can help me out.
Thanks in advance!
public class Datum {
private static String patroon = "\\d{2}-\\d{2}-\\d{4}";
public int dag;
public int maand;
public int jaar;
Datum(int dag, int maand, int jaar) {
System.out.print("constructor: " + dag);
this.dag = dag;
System.out.println(", dag: " + this.dag);
this.maand = maand;
this.jaar = jaar;
}
Datum() {
newDatum();
}
/* */
public static Datum newDatum() {
String input = Opgave5.userInput("Geboortedatum gast");
boolean b = input.matches(patroon);
if (b) {
String[] str = input.split("-");
int dag = Integer.parseInt(str[0]);
int maand = Integer.parseInt(str[1]);
int jaar = Integer.parseInt(str[2]);
Datum datum = new Datum(dag, maand, jaar);
System.out.println(datum);
return datum;
}
else {
return new Datum();
}
}
public String toString() {
return this.dag + "-" + this.maand + "-" + this.jaar;
}
}
Second class:
Gast() {
this.firstName = Opgave5.userInput("Voornaam gast");
this.lastName = Opgave5.userInput("Achternaam gast");
this.geboortedatum = new Datum();
System.out.println("gast: " + this.geboortedatum); // <--- this prints out 0-0-0
}
public String toString() {
return this.firstName + " " + this.lastName + " " + this.geboortedatum;
}
I think you don't understand constructors in Java. You are merely ignoring the result of newDatum() in the constructor. Also, if it did have the expected effect, it might recurse infinitely in the constructor invocation inside newDatum(). Use something like this; allowing newDatum() to edit the instance will work:
Datum() {
newDatum(this);
}
public static void newDatum(Datum instance) {
String input = Opgave5.userInput("Geboortedatum gast");
boolean b = input.matches(patroon);
if (b) {
String[] str = input.split("-");
int dag = Integer.parseInt(str[0]);
int maand = Integer.parseInt(str[1]);
int jaar = Integer.parseInt(str[2]);
instance.dag = dag;
instance.maand = maand;
instance.jaar = jaar;
System.out.println(instance);
}
else {
new Datum();
}
// ^^ Above code may be buggy, see my answer above code
}
This line:
this.geboortedatum = new Datum();
Is using the default constructor. This will set no values. Try to pass the parameters in via constructor like this:
this.geboortedatum = new Datum(1, 2, 3);
If you want to take advantage of the static method you wrote (which is where you ask for user input), then do the following:
this.geboortedatum = Datum.newDatum();
I am writing a program for my assignment, but for my defaultFan and toString methods I am getting an error stating "invalid method declaration; return type required. However I am unsure what how to resolve this. I tried putting void in front of the two methods and it worked but then I get errors stating I cannot assign variables to final variables slow, medium, and fast. I am not sure if this is correct. How would I fix this?
I also have a hard time using test programs. My professor wants us to use a test program that creates 2 fan objets; the first assign maximum speed, radius 10, color yellow and on status. and the second assign medium speed, radius 5 color blue and off status, and to display the fan objects by invoking their toString methods. Would it be possible for someone to explain how test programs work, and how I would go about creating one for this program. Here is my code:
public class fan {
private final int slow = 1;
private final int medium = 2;
private final int fast = 3;
private int speed;
private boolean fanOn;
private double radius;
private String color;
public void defaultFan( )
{
int speed = 1;
boolean fanOn = false;
double radius = 5;
String color = "blue";
}
public fan(final int slow, final int medium, final int fast, int
speed, boolean fanOn, double radius, String color) {
this.slow = slow;
this.medium = medium;
this.fast = fast;
this.speed = speed;
this.fanOn = fanOn;
this.radius = radius;
this.color = color;
}
public final int getSlow(){
return slow;
}
public final int getMedium() {
return medium;
}
public final int getFast() {
return fast;
}
public int getSpeed() {
return speed;
}
public boolean getfanOn() {
return fanOn;
}
public double getradius() {
return radius;
}
public String getcolor() {
return color;
}
public void setSlow(final int slow) {
this.slow = slow;
}
public void setMedium(final int medium) {
this.medium = medium;
}
public void setFast(final int fast) {
this.fast = fast;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public void setFanOn(boolean fanOn) {
this.fanOn = fanOn;
}
public void setRadius(double radius) {
this.radius = radius;
}
public void setColor(String color) {
this.color = color;
}
public void toString() {
if(fanOn = true ) {
System.out.println("The speed of the fan is " + speed + ", the color
of the the fan is " + color + ", and the radius of the fan is " +
radius + ".");
}
else {
System.out.println("The fan is off but the color is " + color +"
and the radius is " + radius + ".");
}
}
}
The variables slow, medium, and fast are final; you set each of them in their declaration, and you need not and cannot reinitialize them. You need to remove them from your constructor:
public fan(int speed, boolean fanOn, double radius, String color) {
this.speed = speed;
this.fanOn = fanOn;
this.radius = radius;
this.color = color;
}
Now, get rid of the setSlow and getSlow methods, etc. Keep the others.
You would want to invoke the constructor with code like:
fan myFan = new fan(/* medium */ 2, true, 10.0, "blue");
// But see 4 and 5 below.
The variables slow, medium, and fast are not tied to any specific instance of fan. So, you want to declare these like so:
public static final int SLOW = 1;
public static final int MEDIUM = 2;
public static final int FAST = 3;
// The constructor call becomes:
fan myFan = new fan(fan.MEDIUM, true, 10.0, "blue");
Typically, classes in Java have capitalized names. Call the class Fan. Replace all instances of fan with Fan.
The toString method should not be so chatty. Typically, people write these methods to help them debug their code, not to provide friendly access to users. Just report the values of the instance variables, which do not include SLOW, MEDIUM, or FAST. Don't use conditional logic.
Your toString method actually overrides the basic one in Object. Java will nag you until you add the #Override annotation. For fun, write your toString code, use it, and then comment the code out. See what happens to the output. You'll see why you need to override the method in Object.
#Override
public String toString() {
return "Fan" + "[speed: " + speed +
",on: " + fanOn +
",radius: " + radius +
",color: " + color + "]";
}
For future work, consider using Java's own Color class instead of a String. Also, consider writing a Java enum of your own named Speed instead of using those three constants.
Ask yourself what someone using the code would want the code to do, both if everything goes right, and if things go wrong or the class is used incorrectly. For example, perhaps the Fan class should obey these rules:
If I construct a Fan, and I ask it for its speed, I get the speed I put in.
Ditto for whether it's on, its radius, and its color.
If I take a Fan, and call a set method on one of its instance variables, and I then query the variable with a get method, I obtain the value I put in.
If I construct a Fan with a negative radius or with null for its color, the constructor fails, throwing an IllegalArgumentException. Your class may not have covered that yet.
Similarly, if I call myFan.setRadius(-10.0), the set method throws the same exception and myFan is left untouched.
If I try to set the speed of a Fan to something other than SLOW, MEDIUM, or FAST, this should fail too. Remember the advice about enums? This is a good reason why.
There are many frameworks to help with software testing; sadly, people don't do it enough in practice. But look up JUnit; your IDE almost certainly has ways to help you create JUnit tests.
Write your toString method like this
public String toString() {
String description = "";
if (fanOn = true) {
description += "The speed of the fan is " + speed
+ ", the color of the the fan is " + color
+ ", and the radius of the fan is " + radius + ".";
} else {
description += "The fan is off but the color is " + color
+ " and the radius is " + radius + ".";
}
return description;
}
I am not sure what you want to do with slow/medium/fast(seems a redundancy with speed). But if you want to modify it, don't declare it as final.
private int slow = 1;
private int medium = 2;
private int fast = 3;
You need a constructor for your test program. (by the way, you should name your class Fan)
public fan(int speed, double radius, String color, boolean fanOn ) {
this.speed = speed;
this.radius = radius;
this.color = color;
this.fanOn = fanOn;
}
Your test program should look like this.
public static void main(String args[]) {
fan fan1 = new fan(100, 100, "red", true);
fan fan2 = new fan(200, 200, "green", false);
}
public void toString()
This is causing the error. Knowingly or Unknowingly, you're trying to override the Object.toString() method, and that's the reason its showing that error. You either need to change the return type of your toString() method to String or change the method name to something else, to avoid conflict with Object.toString().
Apart from the major issue mentioned above, you've a few other bugs as well in your code, which could be resolved with a good IDE.
And for your final question: there are any number of tutorials on testing in Java. Search for JUnit. Here's an example tutorial.