如何将两种方法循环在一起?
Posted
技术标签:
【中文标题】如何将两种方法循环在一起?【英文标题】:How can I loop 2 methods together? 【发布时间】:2022-01-07 11:07:44 【问题描述】:Question
我对 Java 很陌生,我正在努力学习。我要解决的问题的实际问题在上图中。如果我的问题描述不够详细,请参考图片。我目前正在编写一个与购买咖啡有关的 Java 程序。我有一种方法可以计算购买咖啡的成本(BuyCoffee)和使用的资源量。还有不同类型的咖啡,每种咖啡使用不同数量的资源。我还有另一种计算咖啡售出后剩余资源的方法**(getRemainingResources)**。我在循环我的 getRemainingResources 方法时遇到问题。所以当我买一次咖啡时,我拥有的资源量就会减少。我有一种方法来填充这些资源。但是每次我再次尝试购买相同的咖啡时,我剩余的资源量并没有减少。我的代码如下
import java.util.Scanner;
public class MethodsTest
//global variable--starting quantity of resources in machine
static final int water = 400;
static final int milk = 540;
static final int coffeeBean = 120; // in g
static int disposableCups = 9;
static final int cost = 550; //in $
//global variable --refill quantity of resources in machine
static int fillWater, fillMilk, fillCoffeeBeans, fillDisposableCups;
//global variable -- remaining quantity of resources in machine
static int newRemCost, remCost, remWater, remMilk, remCoffeeBean, remDisposableCups;
static int espressoWater, espressoMilk, espressoCoffeeBeans, espressoCost; // Resources for espresso
static int latteWater, latteMilk, latteCoffeeBeans, latteCost;
static int cappuccinoWater, cappuccinoMilk, cappuccinoCoffeeBeans, cappuccinoCost;
static int regWater, regMilk, regCoffeeBeans, regCost; //Resources for regular coffees
static void FillCoffeeMachine()
Scanner input = new Scanner(System.in);
System.out.println("Write how many ml of water you want to add: ");
fillWater = input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
fillMilk = input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
fillCoffeeBeans = input.nextInt();
System.out.println("Write how many disposable cups of coffee you want to add: ");
fillDisposableCups = input.nextInt();
MainMenu();
static void BuyCoffee() //method for buying coffee
disposableCups--;// always decreasing when coffee is sold
class TypesOfCoffee
void Espresso() //nested class, since there are different kind of coffee
espressoWater = 250;
espressoMilk = 0;
espressoCoffeeBeans = 16;
espressoCost = 4;
if (remWater > espressoWater && remMilk > espressoMilk && remCoffeeBean > espressoCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < espressoWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remCoffeeBean < espressoCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void Latte()
latteWater = 350;
latteMilk = 75;
latteCoffeeBeans = 20;
latteCost = 7;
if (remWater > latteWater && remMilk > latteMilk && remCoffeeBean > latteCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < latteWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < latteMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < latteCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void Cappuccino()
cappuccinoWater = 200;
cappuccinoMilk = 100;
cappuccinoCoffeeBeans = 12;
cappuccinoCost = 6;
if (remWater > cappuccinoWater && remMilk > cappuccinoMilk && remCoffeeBean > cappuccinoCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < cappuccinoWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < cappuccinoMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < cappuccinoCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void regularCoffee()
regWater = 200;
regMilk = 50;
regCoffeeBeans = 15;
regCost = 0;
if (remWater > regWater && remMilk > regMilk && remCoffeeBean > regCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < regWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < regMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < regCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
Scanner input = new Scanner(System.in);
System.out.println("What kind of coffee would you like to buy today?");
System.out.println("""
Please enter:
1 for espresso
2 for latte
3 for cappuccino
4 for a regular coffee
back - to go back to main menu""");
String choice = input.next();
switch (choice) //lets user choose what type of coffee to buy
case "1":
new TypesOfCoffee().Espresso();
break;
case "2":
new TypesOfCoffee().Latte();
break;
case "3":
new TypesOfCoffee().Cappuccino();
break;
case "4":
new TypesOfCoffee().regularCoffee();
break;
case "back":
MainMenu();
break;
default:
System.out.println("Please enter an option from the above");
MainMenu();
static void takeMoney() //method to take the money
System.out.println("I gave you" + " " + "$" + remCost);
newRemCost = remCost;
MainMenu();
static void getRemainingResources()
//TODO --has to loop..but it works only once
remDisposableCups = fillDisposableCups + disposableCups;
boolean found = remDisposableCups > 0; // true for coffee to be sold
while (found)
remWater = water + fillWater - espressoWater - cappuccinoWater - latteWater;//
remMilk = milk + fillMilk - espressoMilk - cappuccinoMilk - latteMilk;
remCoffeeBean = coffeeBean + fillCoffeeBeans - espressoCoffeeBeans - cappuccinoCoffeeBeans - latteCoffeeBeans;
remCost = cost + espressoCost + cappuccinoCost + latteCost - newRemCost;
//found = remDisposableCups > 0 && remWater>=water && remMilk>=milk&&remCoffeeBean>=coffeeBean;
System.out.println("The coffee machine has: ");
System.out.println(remWater + " " + "ml of water");
System.out.println(remMilk + " " + "ml of milk ");
System.out.println(remCoffeeBean + " " + "g of coffee beans ");
System.out.println(remDisposableCups + " " + "disposable cups ");
System.out.println("$" + remCost + " " + "of money");
found = remDisposableCups < 0;
MainMenu();
static void MainMenu() // Gives user option to decide what they want to do
Scanner input = new Scanner(System.in);
System.out.println("Main Menu: " + "\n");
System.out.println("Please choose from the following options below");
System.out.println("""
To buy coffee - Enter buy
To fill the machine - Enter fill
To get cash from machine - Enter take
To see remaining resources - Enter remaining
To exit program - Enter exit""");
String choice = input.next();
switch (choice)
case "buy":
BuyCoffee();
break;
case "fill":
FillCoffeeMachine();
break;
case "take":
takeMoney();
break;
case "remaining":
getRemainingResources();
break;
case "exit":
System.exit(0);
break;
default:
MainMenu();//goes back to main menu if user types in an unknown value
public static void main(String[] args)
MainMenu();
【问题讨论】:
只是不要从其他方法调用#MainMenu
,它们会在方法体的末尾返回到调用者(在本例中为#MainMenu
)。使#MainMenu
循环,直到输入“退出”作为选项。最后一个技巧是不要在各种方法中重新初始化 Scanner
对象,而是将单个 Scanner
作为静态资源或作为方法参数传递。这专门针对System.in
上的Scanner
谢谢,我将扫描仪更改为静态资源,并在我的 switch 语句中循环主菜单。我仍然有同样的问题,因为当我尝试使用购买咖啡(两次)购买相同的咖啡时,资源并没有减少。我认为这与我的 getRemainingResource 方法@Rogue 有关
谢谢,我把Scanner改成静态资源,在switch语句块中循环了MainMenu。但我仍然有同样的问题。如果我使用两次购买咖啡,资源(牛奶,水等)的数量应该减少两次,但只会减少一次。这意味着 getRemainingResources 没有循环。剩余的资源量只减少了一次,但应该减少两次(如果我调用两次buyCoffee)即我两次购买相同的咖啡@Rogue
本案例中的资源是牛奶、咖啡豆、水、一次性杯子等
可能是学习如何使用调试器的好时机,它可以让您逐步执行代码并查看变量的值。我会说有一些“设计缺陷”(很多不必要的static
,最好作为个人class
es 的方法)。 TypesOfCoffee
中的大问题是您有正在调用的 方法,并且这些方法都在调用开始时设置了这些常量值。所以TypesOfCoffee#latte
会在每次调用时将latteWater
设置为350
。
【参考方案1】:
现在应该可以了 但是还有其他错误(除了扫描仪,他们已经告诉过你了) 例如,你不能在没有“剩余”的情况下购买咖啡(还有:静态变量太多,OO 没有使用......)。这只是一个例子。 我更正了您要求的错误的代码,但会有很多地方需要更改。
import java.util.Scanner;
public class MethodsTest
//global variable--starting quantity of resources in machine
static final int water = 40000;
static final int milk = 54000;
static final int coffeeBean = 12000; // in g
static int disposableCups = 900;
static final int cost = 550; //in $
static int remCost = 550; //in $
//global variable --refill quantity of resources in machine
static int fillWater, fillMilk, fillCoffeeBeans, fillDisposableCups;
//global variable -- remaining quantity of resources in machine
static int newRemCost, remWater, remMilk, remCoffeeBean, remDisposableCups;
static int espressoWater, espressoMilk, espressoCoffeeBeans, espressoCost; // Resources for espresso
static int latteWater, latteMilk, latteCoffeeBeans, latteCost;
static int cappuccinoWater, cappuccinoMilk, cappuccinoCoffeeBeans, cappuccinoCost;
static int regWater, regMilk, regCoffeeBeans, regCost; //Resources for regular coffees
static void FillCoffeeMachine()
Scanner input = new Scanner(System.in);
System.out.println("Write how many ml of water you want to add: ");
fillWater = input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
fillMilk = input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
fillCoffeeBeans = input.nextInt();
System.out.println("Write how many disposable cups of coffee you want to add: ");
fillDisposableCups = input.nextInt();
MainMenu();
static void BuyCoffee() //method for buying coffee
disposableCups--;// always decreasing when coffee is sold
class TypesOfCoffee
void Espresso() //nested class, since there are different kind of coffee
espressoWater = 250;
espressoMilk = 0;
espressoCoffeeBeans = 16;
espressoCost = 4;
if (remWater > espressoWater && remMilk > espressoMilk && remCoffeeBean > espressoCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < espressoWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remCoffeeBean < espressoCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void Latte()
latteWater = 350;
latteMilk = 75;
latteCoffeeBeans = 20;
latteCost = 7;
if (remWater > latteWater && remMilk > latteMilk && remCoffeeBean > latteCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < latteWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < latteMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < latteCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void Cappuccino()
cappuccinoWater = 200;
cappuccinoMilk = 100;
cappuccinoCoffeeBeans = 12;
cappuccinoCost = 6;
if (remWater > cappuccinoWater && remMilk > cappuccinoMilk && remCoffeeBean > cappuccinoCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < cappuccinoWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < cappuccinoMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < cappuccinoCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
void regularCoffee()
regWater = 200;
regMilk = 50;
regCoffeeBeans = 15;
regCost = 0;
if (remWater > regWater && remMilk > regMilk && remCoffeeBean > regCoffeeBeans)
System.out.println("I have enough resources, making you a coffee!");
else if (remWater < regWater)
System.out.println("Sorry, not enough water!");
disposableCups++;
else if (remMilk < regMilk)
System.out.println("Sorry, not enough milk!");
disposableCups++;
else if (remCoffeeBean < regCoffeeBeans)
System.out.println("Sorry, not enough coffee beans!");
disposableCups++;
else
disposableCups++;
Scanner input = new Scanner(System.in);
System.out.println("What kind of coffee would you like to buy today?");
System.out.println("""
Please enter:
1 for espresso
2 for latte
3 for cappuccino
4 for a regular coffee
back - to go back to main menu""");
String choice = input.next();
switch (choice) //lets user choose what type of coffee to buy
case "1":
new TypesOfCoffee().Espresso();
break;
case "2":
new TypesOfCoffee().Latte();
break;
case "3":
new TypesOfCoffee().Cappuccino();
break;
case "4":
new TypesOfCoffee().regularCoffee();
break;
case "back":
MainMenu();
break;
default:
System.out.println("Please enter an option from the above");
MainMenu();
static void takeMoney() //method to take the money
System.out.println("I gave you" + " " + "$" + remCost);
newRemCost = remCost;
MainMenu();
static void getRemainingResources()
//TODO --has to loop..but it works only once
remDisposableCups = fillDisposableCups + disposableCups;
boolean found = remDisposableCups > 0; // true for coffee to be sold
while (found)
remWater = water + fillWater - espressoWater - cappuccinoWater - latteWater;//
remMilk = milk + fillMilk - espressoMilk - cappuccinoMilk - latteMilk;
remCoffeeBean = coffeeBean + fillCoffeeBeans - espressoCoffeeBeans - cappuccinoCoffeeBeans - latteCoffeeBeans;
remCost = remCost + espressoCost + cappuccinoCost + latteCost - newRemCost;
espressoCost = 0;
cappuccinoCost = 0;
latteCost = 0;
//found = remDisposableCups > 0 && remWater>=water && remMilk>=milk&&remCoffeeBean>=coffeeBean;
System.out.println("The coffee machine has: ");
System.out.println(remWater + " " + "ml of water");
System.out.println(remMilk + " " + "ml of milk ");
System.out.println(remCoffeeBean + " " + "g of coffee beans ");
System.out.println(remDisposableCups + " " + "disposable cups ");
System.out.println("$" + remCost + " " + "of money");
found = remDisposableCups < 0;
MainMenu();
static void MainMenu() // Gives user option to decide what they want to do
Scanner input = new Scanner(System.in);
System.out.println("Main Menu: " + "\n");
System.out.println("Please choose from the following options below");
System.out.println("""
To buy coffee - Enter buy
To fill the machine - Enter fill
To get cash from machine - Enter take
To see remaining resources - Enter remaining
To exit program - Enter exit""");
String choice = input.next();
switch (choice)
case "buy":
BuyCoffee();
break;
case "fill":
FillCoffeeMachine();
break;
case "take":
takeMoney();
break;
case "remaining":
getRemainingResources();
break;
case "exit":
System.exit(0);
break;
default:
MainMenu();//goes back to main menu if user types in an unknown value
public static void main(String[] args)
MainMenu();
【讨论】:
【参考方案2】:您编写的代码非常复杂,这就是为什么您看不到错误所在的原因。几个cmets:
Java 是一种面向对象 (OO) 的语言。 OO 范式围绕创建类及其对象、继承和多态(从父类继承行为但在每个子类中的行为不同)展开。 您的代码看起来像是在尝试像旧版本的 Basic 或 Macro Assembler 一样重新创建结构化编程,只需遵守 Java 的语法。您需要真正了解 OO 编程的工作原理,因此请先尝试查找相关教程。 不要在一个大类中实现所有内容。尝试识别应用程序中的不同实体。例如:CoffeMachine、Coffee、Espresso、Latte、RegularCoffee……为每个识别的实体创建一个类。彼此相似的类可能应该是继承的一部分,例如 Espresso、Lattte 等应该继承更通用的类 Coffee(当您可以说“A 是 B 的一种”时,A 继承了 B)。 不要使用静态变量(除非有很好的理由,但这种情况很少见)。让每个类在创建对象时都有自己的实例属性:remainingWater、remainingMilk 等是对象 CoffeeMachine 的属性。它们不是全球性的东西。 不要使用静态方法,如 C 或 Basic 中的子例程。相反,创建类的对象并调用它们的实例方法。 不要像在 Basic 或 Assembler 中那样使用跳转和标签。相反,在循环中调用对象的方法并在必要时中断循环。 如果您在应用程序中检测到错误,请利用 Java 的 Exception 机制 - 抛出异常并让调用者处理错误。 Java 中的方法名称以小写字母开头(这是普遍接受的约定,而不是句法规则)。我为您的应用程序创建了一个符合上述原则的不同设计,因此首先从教程中学习面向对象编程的基础知识,然后将以下代码与您的代码进行比较,看看有什么不同。
主类(主菜单循环的入口点):
public class Main
public static void main(String[] args)
new Main().run();
void run()
CoffeeMachine coffeeMachine = new CoffeeMachine(400, 540, 120, 9, 550);
while (coffeeMachine.mainMenu()); // loops until mainMenu returns false
咖啡机:
import java.util.Scanner;
public class CoffeeMachine
private Scanner input = new Scanner(System.in);
private int water;
private int milk;
private int coffeeBeans;
private int disposableCups;
private int money;
public CoffeeMachine(int water, int milk, int coffeeBeans, int disposableCups, int money)
this.water = water;
this.milk = milk;
this.coffeeBeans = coffeeBeans;
this.disposableCups = disposableCups;
this.money = money;
void fill()
System.out.println("Write how many ml of water you want to add: ");
water += input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
milk += input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
coffeeBeans += input.nextInt();
System.out.println("Write how many disposable cups for coffee you want to add: ");
disposableCups += input.nextInt();
public void selectCoffee()
while (true)
System.out.println("What kind of coffee would you like to buy today?");
System.out.println(
" Please enter:\n" +
" 1 for espresso\n" +
" 2 for latte\n" +
" 3 for cappuccino\n" +
" 4 for a regular coffee\n" +
" back - to go back to main menu");
String choice = input.next();
try
switch (choice) //lets user choose what type of coffee to buy
case "1":
buy(new Espresso());
return;
case "2":
buy(new Latte());
return;
case "3":
buy(new Cappuccino());
return;
case "4":
buy(new RegularCoffee());
return;
case "back":
return;
default:
System.err.println("Please enter an option from the above");
catch (InsufficientResourcesException exception)
System.err.println("Error buying coffee: " + exception.getLocalizedMessage());
public void buy(Coffee coffee) throws InsufficientResourcesException
if (coffee.getWaterCost() > water)
throw new InsufficientResourcesException("water", "ml", coffee.getWaterCost(), water);
if (coffee.getMilkCost() > milk)
throw new InsufficientResourcesException("milk", "ml", coffee.getMilkCost(), milk);
if (coffee.getCoffeeBeansCost() > coffeeBeans)
throw new InsufficientResourcesException("coffee beans", "g", coffee.getCoffeeBeansCost(), coffeeBeans);
if (disposableCups < 1)
throw new InsufficientResourcesException("disposable cups", "units", 1, disposableCups);
System.out.println("Buying 1 cup of " + coffee.getClass().getSimpleName());
water -= coffee.getWaterCost();
milk -= coffee.getMilkCost();
coffeeBeans -= coffee.getCoffeeBeansCost();
disposableCups--;
money += coffee.getMoneyCost();
public void takeMoney()
System.out.println("I gave you $" + money + ". The money tray is now empty.");
money = 0;
public void showResources()
System.out.println("The coffee machine has: ");
System.out.println(water + " ml of water");
System.out.println(milk + " ml of milk ");
System.out.println(coffeeBeans + " g of coffee beans ");
System.out.println(disposableCups + " disposable cups ");
System.out.println("$" + money + " of money");
public boolean mainMenu() // Gives user option to decide what they want to do
System.out.println("Main Menu: " + "\n");
System.out.println("Please choose from the following options below");
System.out.println(
" To buy coffee - Enter buy\n" +
" To fill the machine - Enter fill\n" +
" To get cash from machine - Enter take\n" +
" To see remaining resources - Enter remaining\n" +
" To exit program - Enter exit");
String choice = input.next();
switch (choice)
case "buy":
selectCoffee();
break;
case "fill":
fill();
break;
case "take":
takeMoney();
break;
case "remaining":
showResources();
break;
case "exit":
return false;
return true;
还有咖啡课:
public abstract class Coffee
private int waterCost;
private int milkCost;
private int coffeeBeansCost;
private int moneyCost;
protected Coffee(int waterCost, int milkCost, int coffeeBeansCost, int moneyCost)
this.waterCost = waterCost;
this.milkCost = milkCost;
this.coffeeBeansCost = coffeeBeansCost;
this.moneyCost = moneyCost;
public int getWaterCost()
return this.waterCost;
public int getMilkCost()
return this.milkCost;
public int getCoffeeBeansCost()
return this.coffeeBeansCost;
public int getMoneyCost()
return this.moneyCost;
public class Espresso extends Coffee
public Espresso()
super(250, 0, 16, 4);
public class Cappuccino extends Coffee
public Cappuccino()
super(200, 100, 12, 6);
public class Latte extends Coffee
public Latte()
super(350, 75, 20, 7);
public class RegularCoffee extends Coffee
public RegularCoffee()
super(200, 50, 15, 0);
最后但同样重要的是,异常类:
public class InsufficientResourcesException extends Exception
private static final long serialVersionUID = 1L;
public InsufficientResourcesException(String whatResource, String unit, int required, int available)
super("Insufficient resources: required " + required + " " + unit + " of " + whatResource + " but available " + available + " " + unit);
拥有良好的架构对于软件来说是最重要的。如果您的架构被正确应用,错误将是不可能的,如果它们发生,它们将很容易修复。此外,更改具有良好架构的应用程序既简单又安全。
另一方面,糟糕的架构几乎肯定会导致错误,难以找到和修复,并且应用无法轻易更改。
【讨论】:
您好,感谢您向我展示这个结构。我对它不是很熟悉,但现在我知道我在 Java 中有很多东西要学。程序现在运行,遵循这个原则循环。我的是非常基本的@roccobaroccoSC 别担心。学习 OO 并不难,你只需要阅读一个好的教程并了解对象是如何工作的。重要的是不要使用其他语言(如 C)中常见的模式,因为它们会使您的代码变得不必要地复杂。总是从设计你的课程开始。当你描述你的应用程序做什么时,通常你使用的每个名词都应该代表一个对象,它是一个类的实例。短语“is a kind of”表示继承,所有动词都表示类的方法。这是对代码建模的一个很好的开始。以上是关于如何将两种方法循环在一起?的主要内容,如果未能解决你的问题,请参考以下文章