In my do while loop, the body works fine initially, but when it loops, it prints the first two statements like it should but it does not allow me to enter the name instead it goes straight to enter pin and whatever I enter it skips the rest and asks me if I want another transaction.
I have an array object partially filed. The variables in the object are name, pin, account number and balance. When I add a new object and set the balance, the new balance I enter causes the balance for the previous objects to change as well. I think it has something to do with the balance variable being declared as static but I don't make it static, i can the error "Cannot make a static reference to the non-static method withdraw(double) from the type CustomerRecord". (SOLVED) Thank you.
public class BankCustomers
{
public static void main(String[] args)
//------------------------------------------------
//Part4: Find a customer record from anotherArray
//to do transaction(s) and update the record's balance
char repeat; // User control to repeat or quit
Scanner keyboard = new Scanner(System.in); //creating the scanner
String aName;
int aPin;
double aWithdraw;
double aDeposit;
do{
//Read customer information before search
System.out.println();
System.out.println("Lets make a transaction");
System.out.println("Enter customer full name");
aName = keyboard.nextLine( );
System.out.println("Enter Pin");
aPin = keyboard.nextInt();
//Search an Array for equal aName and aPin
for (int i = 0; i < index; i++)
{
CustomerRecord cRecord = anotherArray[i];
if((cRecord.getName().equalsIgnoreCase(aName)) && (cRecord.getPin() ==(aPin)))
{
System.out.println(cRecord);
System.out.println("Enter Withdraw Amount");
aWithdraw = keyboard.nextDouble();
CustomerRecord.withdraw(aWithdraw);
System.out.println("Enter Deposite Amount");
aDeposit = keyboard.nextDouble();
CustomerRecord.deposit(aDeposit);
System.out.println(cRecord);
}
}
System.out.println("\nAnother Transaction? (y for yes)");
repeat = keyboard.next().charAt(0);
}while(repeat == 'y' || repeat == 'Y');
//Print the records on screen
for (int i = 0; i < index; i++)
System.out.print(anotherArray[i]);
}
Remove the static from
private static double balance
and
public static void deposit(double aDeposit)
and
public static void withdraw(double aWithdraw)
you don't want them to be static as you are going to call these methods directly from the objects you created, so they will be specific to each CustomerRecord.
Then in your code, change these lines:
CustomerRecord.deposit(aDeposit);
CustomerRecord.withdraw(aDeposit);
by:
cRecord.deposit(aDeposit);
cRecord.withdraw(aDeposit);
The modifications made now will be applied to each CustomerRecord balance variable and not to a single balance variable (unique for the whole program) as it was the case when it was static.
public class CustomerRecord implements Serializable
{
private String name;
private int pin;
private int account;
private double balance;
}
public void deposit(double aDeposit)
{
balance = balance + aDeposit;
}
public void withdraw(double aWithdraw)
{
if (balance >= aWithdraw) balance = balance - aWithdraw;
else System.out.println("Withdraw cannot be negativeegative");
}
Make balance non-static, as you mentioned. This will fix the bug.
Make the CustomerRecord#deposit() and #withdraw() methods non-static as well. This will fix the compile error caused by #1.
You're correct that the problem is that you made things static. None of balance, deposit, withdraw should be static because all of them are things that apply to a particular customer record rather than to all customer records simultaneously.
The fact that your code doesn't work when you don't make them static is related to the way in which you're calling the withdraw method: CustomerRecord.withdraw(aWithdraw). Can you see what's wrong with that, now that your attention is drawn to it?
In your instance variables for CustomerRecord you have balance declared as a static variable.
This means that anytime you change balance in one instance of the class that it will change in all instances. For example, the deposit and withdraw methods.
I assume you needed to make balance static in order for these two methods to work, but you should just take the static declaration out of all three. Then, you need to change all calls from
CustomerRecord.withdraw();
CustomerRecord.deposit();
to use an instance of a class rather than just the static class. So,
// Whatever values you want here, you seem to have 4 already declared so you can use those
CustomerRecord c = new CustomerRecord("", 0, 0, 0);
c.withdraw();
c.deposit();
Your problem is twofold:
First, balance istatic, which means it is associated with the class, not any of its instances (objects), or in other terms it is shared between all instances of that class.
Second, as you pointed it out, your static method withdraw is accessing balance. The consideration about static applies here just as well -- the method is associated with the class, and cannot access memebers that are non-static.
To solve the second problem, remove static from the withdraw declaration (and remove static from balance as well. Thyis will make your code CustomerRecord.withdraw() not compile, becuase withdraw is now not associated with the class itself, but an instance of it. So you need to use an instance and call withdraw on that
cRecord.withdraw(aWithdraw);
Similarly for deposit
Related
I'm learning Java on Codecademy and recently completed a project that calculates monthly payments for a car loan. The problem is that I don't understand the solution, and no one has responded to my question about it on the Codecademy forum.
Why are the instance variables created in the main method scope instead of just after the class has been declared? We haven’t seen any examples of this prior to this project and I don’t understand.
Here is the code:
//Calculates monthly car payment
public class CarLoan {
//Why aren't the variables created here rather than in the main method?
public static void main(String[] args) {
int carLoan = 10000;
int loanLength = 3;
int interestRate = 5;
int downPayment = 2000;
if (loanLength <=0 || interestRate <=0) {
System.out.println("Error! You must take out a valid car loan.");
} else if (downPayment >= carLoan) {
System.out.println("The car can be paid in full.");
} else {
int remainingBalance = carLoan - downPayment;
int months = loanLength * 12;
int monthlyBalance = remainingBalance / months;
int interest = (monthlyBalance * interestRate) / 100;
int monthlyPayment = monthlyBalance + interest;
System.out.println(monthlyPayment);
}
}
}
Variables defined within a method are local variables, they belong to an invocation of the method, not to an instance of an object.
The intent seems to be to provide an example that is understandable to beginners who haven't been introduced to constructors, instance variables, and methods. They want to teach local variable declaration, some simple calculating and if-statements, and printing to the console before getting into that other stuff.
As an exercise it would be fine for you to change the CarLoan class to give it instance variables, just to see another way to do it. Keep the variable values hard-coded, make an instance method that calculates the monthly payment, and have the main method print the result to the console.
So I created Saving class, created also setters and getters. Now I need u method, which will calculate the total amount of deposits.
public class Saving {
private double deposits;
private double totalAmountOfDeposits;
public double getDeposits()
{
return deposits;
}
public void setDeposits(double deposits)
{
this.deposits = deposits + deposits;
}
public double getTotalAmountOfDeposits()
{
double total = 0;
return total = total + deposits;
}
}
When I use this class in the program I got a wrong calculation. The program just add first value of deposit to the first value.
import java.util.Scanner;
public class SavingDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Saving save = new Saving();
System.out.println("Deposit amount");
double depositeAmount = input.nextDouble();
save.setDeposits(depositeAmount);
System.out.println("Deposit amount");
double depositeAmount2 = input.nextDouble();
save.setDeposits(depositeAmount);
System.out.println("Deposit amount");
double depositeAmount3 = input.nextDouble();
save.setDeposits(depositeAmount);
System.out.println("The total amount has been deposited is " + save.getTotalAmountOfDeposits());
}
}
And here is the output:
Deposit amount
12
Deposit amount
34
Deposit amount
56
The total amount has been deposited is 24.0
As you can see its just added 12 to 12. Just want to mention that I'm totally new in programming. Les than a month.
I see two problems in your code. Take a look at the commented line. The reason you are seeing 12 + 12 is because that is exactly what you are instructing the JVM to do.
System.out.println("Deposit amount");
double depositeAmount = input.nextDouble();
save.setDeposits(depositeAmount);
System.out.println("Deposit amount");
double depositeAmount2 = input.nextDouble();
save.setDeposits(depositeAmount); // <= adds the wrong variable
System.out.println("Deposit amount");
double depositeAmount3 = input.nextDouble();
save.setDeposits(depositeAmount); // <= adds the wrong variable
System.out.println("The total amount has been deposited is " + save.getTotalAmountOfDeposits());
Secondly, it looks like you may have a design flaw in your implementation of the Saving class.
You'll want to brush up on variable scope
If you take a look at your implementation on your total:
public double getTotalAmountOfDeposits()
{
double total = 0;
return total = total + deposits;
}
You have the total starting at 0 every time this method getTotalAmountOfDeposits() is called. the total variable in this method is local to it's method. So what you currently have is a method variable
You'll want to do some research into class variable. This will maintain that the instance of the object will have this variable assigned through the life cycle of the instantiated object.
When you have variables of the same name, you can get the instance variable with this keyword.
So when dealing with your setter
public void setSomething(double something) {
this.something // class variable
something // method variable
}
If you want your object to maintain state, you can set it on your object itself, and have your set deposit modify that state. Some pseudo code to get you moving forward.
public class Saving {
private double totalAmountOfDeposits; // you can modify this value with public methods
public void setDeposit(_) {
// Setter implementation
// increment totalAmountOfDeposits;
public double getTotalAmountOfDeposits(_)
// return totalAmountOfDeposits;
}
You should write a method
public void addDeposits(double deposits)
{
this.deposits = this.deposits + deposits;
}
and change setDeposits to
public void setDeposits(double deposits)
{
this.deposits = deposits;
}
after this call addDeposits to add deposits
To eliminate confusion within the Saving Class change the argument name for the setDeposits() method to double newDeposit instead of double deposits which is also a class field name. Although the construct is legal it does make it a wee bit confusing. Inside the setDeposits() method use:
this.deposit+= newDeposit;
As a matter of fact, you can get rid of the deposits field altogether since you also have the field named totalAmountOfDeposits. Use that instead:
this.totalAmountOfDeposits+= newDeposit;
You might also want a clearDeposits() method in your Saving Class:
public void clearDeposits() {
this.totalAmountOfDeposits = 0.0;
}
Your getTotalAmountOfDeposits() method within the Saving Class doesn't really make any sense either. Since you are always summing deposits anyways you can just return what is held within the totalAmountOfDeposits field:
public double getTotalAmountOfDeposits() {
return totalAmountOfDeposits;
}
The above method is would now of course be very mush the same as the getDeposits() method which could be changed to getTotalDeposits(). You can then change the getTotalAmountOfDeposits() method name to getTotalNumberOfDeposits() and add a additional class field named numberOfDeposits:
private double totalAmountOfDeposits;
private int numberOfDeposits = 0;
public double getTotalDeposits() {
return totalAmountOfDeposits;
}
public int getTotalNumberOfDeposits() {
return numberOfDeposits;
}
and in your setDeposits() method add the code line:
numberOfDeposits++;
So that it would look something like:
public void setDeposits(double newDeposit) {
totalAmountOfDeposits+= newDeposit;
numberOfDeposits++;
}
If you do add a clearDeposits() method to your Saving Class then don't forget to add the code line: numberOfDeposits = 0; into that method as well. It might now look something like:
public void clearDeposits() {
totalAmountOfDeposits = 0.0;
numberOfDeposits = 0;
}
You also have some issues within your main() method of your SavingDemo Class. Take a real close look at each call you make to the setDeposits() method for each value the User supplies. Each User supplied value goes into a specific double type variable name. Is that what you are passing to the setDeposits() method? ;)
Once you've got all that taken care of you can display to console:
System.out.println("The total amount has been deposited is " +
save.getTotalDeposits() + " by making " +
save.getTotalNumberOfDeposits() + " deposits.");
Right now, I'm learning all about class, constructors and instances. I've made a small bit of code in java and I'm stuck with this particular code.
***MY CODE OUTPUT IS SUPPOSE TO BE LIKE THIS:
OUTPUT
Enter amount:500
Do you want to enter amount again?(y/n):y
Enter amount:45
Do you want to enter amount again?(y/n):n
TOTAL:545
***BUT INSTEAD MY OUTPUT IS LIKE THIS:
OUTPUT
Enter amount:500
Do you want to enter amount again?(y/n):y
Enter amount:45
Do you want to enter amount again?(y/n):n
TOTAL:45
***It is not adding the amount that I enter throughout the loop and instead, it is giving me the very last amount that I input.
Here is the first code:
public class Test {
private double money;
public Test(){
}
public void addPoints(double money1){
money += money1;
}
public int getMoney(){
return money;
}
}
and the second code is here:
import java.util.Scanner;
public class testBody {
public static void main(String[]args){
double cashMoney;
String response = "";
Scanner hold = new Scanner(System.in);
do{
System.out.print("Enter amount:");
cashMoney = hold.nextDouble();
Test cashPlus = new Test();
cashPlus.addPoints(cashMoney);
System.out.print("Do you want to enter amount again?(y/n):");
response = hold.next();
if(response.equalsIgnoreCase("n")){
System.out.print("TOTAL: " + cashPlus.getMoney());
}
}while(response.equalsIgnoreCase("y"));
}
}
You should create the Test instance before the loop instead of in each iteration.
Test cashPlus = new Test();
do {
System.out.print("Enter amount:");
cashMoney = hold.nextDouble();
cashPlus.addPoints(cashMoney);
System.out.print("Do you want to enter amount again?(y/n):");
response = hold.next();
if(response.equalsIgnoreCase("n")){
System.out.print("TOTAL: " + cashPlus.getMoney());
}
} while(response.equalsIgnoreCase("y"));
Each time you create a new Test instance, cashMoney is initialized to 0 (since each instance has its own value of that member). When you finally print cashPlus.getMoney(), you print the value of the last instance you created, to which you only added the final amount you entered.
In the line Test cashPlus = new Test(); you are creating a new Test object every time a value is entered. This effectively resets the already existing sum, because in the new class Test.money equals 0 again.
The issue is this line being inside the do/while loop:
Test cashPlus = new Test();
The Test class object holds the variable money (which is initialized to 0) and you are creating a new instance of it with each iteration of the do/while loop, thus resetting cashPlus.money to 0.
Just move that line before of the do/while and you should be fine!
In the loop , you are creating
Test cashPlus = new Test();
with this statement every time you are creating new object and adding sum to it. In all it is added to a new value as with new object it initialized to 0.
To avoid this instantiate the
Test cashPlus = new Test();
before starting the loop.
replace
private double money;
with
private static int money;
Everytime you set the value, it becomes 0. To pertain the value make it a static variable.
Note that the return type of getMoney is int and the datatype of money is double. This has to be type-casted or changed to similar data-type.
This is a pretty common problem I run into when I'm programming, and I'm a beginner so it stumps me for whatever reason. Here's my code:
boolean valid = false;
do {
double newPrice;
System.out.print("Enter new price: $");
newPrice = scan.nextDouble();
if(newPrice > 0){
b[bookChosen].price() = new newPrice;
valid = true;
}
}while(!valid);
The newPrice double in the if-statement cannot be found, and I know why, I just can't think of a way to be able to see if the user's input is a viable number.
Thanks in advance.
You've got a couple of fundamental things wrong with your code, all centered on the line:
b[bookChosen].price() = new newPrice;
First of all, new newPrice doesn't do anything and won't even compile. new is a keyword for creating new objects, and must be followed with an invocation of a class's constructor -- newPrice is not a class, nor is it an invocation of a class's constructor.
Secondly, you're attempting to assign to the invocation of an object's method. You cannot assign to an invocation of an object's method -- you can only assign to names.
What you probably meant to do is something like:
b[bookChosen].setPrice(newPrice);
This uses a setter to set the price of the object contained at b[bookChosen]. Using setters to change the property of an object is an extremely common convention in Java. You probably wouldn't be having these issues if you were using an IDE, which is the only way anyone ever really writes modern Java (enter obligatory plug for https://www.jetbrains.com/idea/), and you'd probably learn a whole lot.
Other than that, your code is generally fine, although I think it's a little simpler written:
while (true) {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
if (newPrice > 0) {
b[bookChosen].setPrice(newPrice);
break; // leave while True loop
}
}
An alternative control flow that's not quite as natural for me, is:
double newPrice = 0;
while (newPrice <= 0) {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
}
b[bookChosen].setPrice(newPrice);
new newPrice;
new keyword is always used to create a new object not to assign a new value (this is what i understanded from your code)
b[bookChosen].price()
of what ever class b is the array of that. You are assigning a value to that at the index bookChosen.
If price is you method, then values are not assigned to methods, values are send through parameters to method.
like b[bookChosen].price(newPrice);
If price is your field of that class, then it must b public or protected if it is in the same package. then variables of class are
not post pended by (). they are assigned like b[bookChosen].price = newPrice;
but it not standard always make your bean by private fields and access then through setter getters.
boolean valid = false;
do {
System.out.print("Enter new price: $");
double newPrice = scan.nextDouble();
if(newPrice > 0){
b[bookChosen].setPrice(newPrice) ;
valid = true;
}
}while(!valid);
Best Of Luck.
So I am trying to write a simple program for my Java class and I have asked the teacher for help however, this is a distance learning class and am not getting much help from that direction. So here I am.
The problem we have been asked to solve is to create a program that will
(1) ask the user for a number ,
(2) find the sum of all user defined numbers ,
(3) find the average of these numbers ,
(4) then out put them back to the user.
I use the numbers not only to line through things I have finished but because they must be separate modules to be called.
How can i get the userNum variable to update durring the while statments. Currently they are not. OR is there a simpler way to do this that im overlooking. Any help is greatly appreciated. Thank you.
public class P2 {
public static void main(String[] args) {
int userNumCount = 1;
double userNum = input();
double userSum = sum(userNum);
double userAverage = average(userSum, userNumCount);
sum(userNum);
while (userNum != 0 && sum(userNum) <= 100){
++userNumCount;
output(userSum, userAverage);
input();
sum(userNum);
average(userSum, userNumCount);
}//end else
while (userNum != 0 && sum(userNum) >=100){
++userNumCount;
JOptionPane.showMessageDialog (null, "Warning, your sum is currently over 100!!!!!");
output(sum(userNum), userAverage);
input();
sum(userNum);
average(userSum, userNumCount);
}//end else
if (input() == 0){
output(userSum, userAverage);
JOptionPane.showMessageDialog (null, "Thank you for using this program have a nice day.");
}//end else if
}//end main module
public static double input(){
String userNumString;
userNumString = JOptionPane.showInputDialog("Please enter your number or input 0 to end the program.");
double userInput = Double.parseDouble (userNumString);
return userInput;
}//end input module
public static double sum(double userNum){
double userSum =+userNum;
return userSum;
}//end sum module
public static double average (double userSum, int userNumCount){
double userAverage = userSum/userNumCount;
return userAverage;
}//end average module
public static void output (double userSum, double userAverage){
JOptionPane.showMessageDialog (null, "The sum of the numbers input so far is: " + userSum + ". And the Average is " + userAverage + "." );
}//end output module
}//end class
All of the values returned from methods in your main are just returning their values to nothing. When you pass variables to a function, they are passed by value. For example:
public void main(String args[]){
int f = 5;
doSomething(f);
System.out.println(f);
}
public int doSomething(int i){
i+=1;
return i;
}
The value returned by doSomething is 6, but the program outputs 5. When you call a function the int i is recreated independently of f. As of now, your program is just throwing those values away and keeping the old ones.
Also you have the variables in main called userSum, and userAverage, and in sum and average you redefine these in a different scope. When code flow comes into sum and average it creates new variables for that method. If you want these values to be the same you need to make them static, by defining them outside of your main method and declaring them static.
I think the problem you might be struggling with is scope. Pretty much every time you have an opening bracket the program changes scope. When a block is closed (when there is a closing bracket}, the scope of the variables ends, ie. they don't exist anymore. For example:
class someClass
{
//Block 0
static int staticNum = 0;
public static main(String args[])
{
//Block 1
int level1 = 0;
if(true)
{
//Block 2
int level2 = 0;
} else {
//Block 3
level1++; //ok because the level1 is accessible from here
staticNum++; //ok because staticNum is static
}
//resume block 1
level2++; //not ok because level2 was in a different scope
doSomething(level1)
}
public static void doSomething(int i){
//Block 5
int level1 = 0; //different than the one in the main method
i++; //ok but once execution leaves i wont exist anymore
staticNum++; //ok because staticNum is static and exists in the class's scope
level1++; //not ok because level1 is not defined for this scope
}
}
While execution is in a block, it can access any variable in blocks 'above' it in nesting level. Looking at the above, in Block 2 and 3 you can access anything in block 1 or block 0. Block 3 doesn't have access to the variables in block 2 because they are out of scope of one another, because when a block closes all variables instantiated in that block are freed. Block 5 has a completely different scope than block 1,2 and 3.
Block 0 is special because it is associated with the class. Anything outside of method bodies declared static are class wide variables, as in you can access it where ever you have access to the class. You would use something like ClassName.staticNum to access it in another class. Also when you access it inside of the class, any methods that you use the static values in need to be declared static as well.
Anything not declared static in the class body is an instance variable. It is associated with an instances of the class, these instances called objects. A class defines the template of an object. For example, lets say we have two objects of type Computer. The class Computer defines what variables each individual computer has(instance variables), and what variables every computer shares(static variables). So if I have Computer A with instance variables mouse and keyboard, it is completely different from another Computer B instance variables mouse and keyboard, but they can share a static variable called Computer.innernette.
This is incorrect.
public static double sum(double userNum){
double userSum =+userNum;
return userSum;
}
In a basic pseudo-language this is happening each time this method is called
receive userNum
create userSum
set userSum = 0
add userNum to userSum
give userSum
each time the method will return the value it is given, not the running total I think you are expecting.
If you have two variables declared with the same name, they are still different. What you want to do is refer to the same variable, to do this you need to have the references in the scope where the variable is declared.
to get the running total
public class P2 {
public static double userSum = 0;
//because this is a public member it's scope is global i.e. you can refer to it anywhere.
...
public static void main(String[] args) {
...
/* do not declare userSum here.
if you do any reference to userSum will use the local variable
not the global variable.
double userSum = 0; <-- declare local variable it's scope is until the
end of this method nothing outside the method
can see it but you can pass it as a parameter
userSum = 1; <-- local variable is set to 1
P2.userSum = 2; <-- local variable is set to 1 global is set to 2
*/
input();// for this the input method is called and returns a value,
// but you haven't said to put it anywhere so java will throw it away
// all that effort for nothing.
userNum = input(); // in this case it will put the new value in userNum.
}
public static double sum(double userNum){
userSum =+userNum; // do not declare userSum use it from the class context
return userSum;
}
...
}
for further reference scope