简体   繁体   English

Java方法传回不正确的值

[英]Java method returning incorrect values

I'm struggling learning to properly code methods in Java. 我正在努力学习如何用Java正确编码方法。 I've looked at many examples and can't see what I'm doing wrong. 我看了很多例子,看不到我在做什么错。 I've got a main class called InvoiceApp which uses a class called Validator to screen input and then a class called Invoice which processes the user input. 我有一个名为InvoiceApp的主类,它使用一个名为Validator的类来筛选输入,然后使用一个名为Invoice的类来处理用户输入。 When InvoiceApp is run, the user inputs either 'r' or 'c' as the Customer Type, and a double value for "subtotal". 运行InvoiceApp时,用户输入“ r”或“ c”作为客户类型,并输入“小计”的双精度值。 The app creates an object of the Invoice class to use the getInvoice() method, which returns a formatted invoice. 该应用程序创建Invoice类的对象以使用getInvoice()方法,该方法返回格式化的发票。 The formatted invoice is returned, but with NULL value for the String and ZEROES for all the numbers (except that which the user input in the 1st place). 返回格式化的发票,但所有数字的字符串为NULL,零号为零(用户在第一位输入的数字除外)。 The Invoice class is apparently not assigning values to the variables. 发票类显然未将值分配给变量。 I've done this many, many different ways and cannot get the thing to work. 我已经完成了许多很多不同的方式,无法使事情正常进行。

Can anyone see what I've done wrong? 谁能看到我做错了什么? Here is my code: 这是我的代码:

The InvoiceApp class: InvoiceApp类:

import java.util.Scanner;

public class InvoiceApp
{    
public static void main(String[] args)
{
    // display a welcome message
    System.out.println("Welcome to the Invoice Total Calculator");
    System.out.println();  // print a blank line

    Scanner sc = new Scanner(System.in);
    String choice = "y";
    while(choice.equalsIgnoreCase("y"))
    {
        // get user entries
        String customerType = Validator.getString(sc,
            "Enter customer type (r/c):   ");
        double subtotal = Validator.getDouble(sc,
            "Enter subtotal:              ", 0, 10000);

        Invoice i;
        i = new Invoice(customerType, subtotal);
        System.out.println();
        System.out.println(i.getInvoice());

        System.out.println();
        System.out.print("Continue? (y/n): ");
        choice = sc.next();
        System.out.println();
    }
} 
}

The Invoice class: 发票类:

import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private final double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setDiscountPercent(double discountPercent){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            discountPercent =.1;
        else if (subtotal < 100)
            discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            discountPercent = .2;
    }
    else
    {
        discountPercent = .05;
    }
}
public double getDiscountPercent(){
    return discountPercent;
}
public void setDiscountAmount(double discountAmount){
    discountAmount = subtotal * (getDiscountPercent());
}
public double getDiscountAmount(){
    return discountAmount;
}
public void setInvoiceTotal(double invoiceTotal){
    invoiceTotal = subtotal - (getDiscountAmount());
}
public double getInvoiceTotal(){
    return invoiceTotal;
}
public void setCustomerType(String sCustomerType){
    sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            sCustomerType = "College";
}
public String getCustomerType(){
    return sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    sCustomerType = this.getCustomerType();
    discountPercent = this.getDiscountPercent();
    discountAmount = this.getDiscountAmount();
    invoiceTotal = this.getInvoiceTotal();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(subtotal) + "\n"
                   + "Customer type:    " + sCustomerType + "\n"
                   + "Discount percent: " + percent.format(discountPercent)+ "\n"
                   + "Discount amount:  " + currency.format(discountAmount)+ "\n"
                   + "Total:            " + currency.format(invoiceTotal) + "\n");
    return invoice;
}
}

The Validator class: Validator类:

import java.util.Scanner;

public class Validator
{
public static String getString(Scanner sc, String prompt)
{
    System.out.print(prompt);
    String s = sc.next();  // read user entry
    sc.nextLine();  // discard any other data entered on the line
    return s;
}

public static int getInt(Scanner sc, String prompt)
{
    int i = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        System.out.print(prompt);
        if (sc.hasNextInt())
        {
            i = sc.nextInt();
            isValid = true;
        }
        else
        {
            System.out.println("Error! Invalid integer value. Try again.");
        }
        sc.nextLine();  // discard any other data entered on the line
    }
    return i;
}

public static int getInt(Scanner sc, String prompt,
int min, int max)
{
    int i = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        i = getInt(sc, prompt);
        if (i <= min)
            System.out.println(
                "Error! Number must be greater than " + min + ".");
        else if (i >= max)
            System.out.println(
                "Error! Number must be less than " + max + ".");
        else
            isValid = true;
    }
    return i;
}

public static double getDouble(Scanner sc, String prompt)
{
    double d = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        System.out.print(prompt);
        if (sc.hasNextDouble())
        {
            d = sc.nextDouble();
            isValid = true;
        }
        else
        {
            System.out.println("Error! Invalid decimal value. Try again.");
        }
        sc.nextLine();  // discard any other data entered on the line
    }
    return d;
}

public static double getDouble(Scanner sc, String prompt,
double min, double max)
{
    double d = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        d = getDouble(sc, prompt);
        if (d <= min)
            System.out.println(
                "Error! Number must be greater than " + min + ".");
        else if (d >= max)
            System.out.println(
                "Error! Number must be less than " + max + ".");
        else
            isValid = true;
    }
    return d;
}
}

Thanks to anyone that can help 感谢任何可以提供帮助的人


Thank you all. 谢谢你们。 I removed the parameters from the setter methods and added this. 我从setter方法中删除了参数,并添加了它。 to the constructors. 给建设者。 Obviously, there are two major areas that I'm confused about: 显然,我对两个主要领域感到困惑:

  1. What parameters are supposed to be in the set methods? 设置方法中应该包含哪些参数? I tried to insert the variables that the set methods actually use , but that didn't work either. 我试图插入设置方法实际使用的变量,但这也不起作用。

  2. I thought get methods were simply used to return the values generated by the set methods. 我认为get方法仅用于返回set方法生成的值。 Since the setters are all void, they can't be directly used. 由于设置器都是无效的,因此不能直接使用。 Working examples I've seen are constructed similarly (however they actually work). 我见过的工作示例的构造类似(但是它们实际起作用)。

Here is what I changed in the Invoice class. 这是我在“发票”类中所做的更改。

    import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private final double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setDiscountPercent(){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            this.discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            this.discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            this.discountPercent =.1;
        else if (subtotal < 100)
            this.discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            this.discountPercent = .2;
    }
    else
    {
        this.discountPercent = .05;
    }
}
public double getDiscountPercent(){
    return this.discountPercent;
}
public void setDiscountAmount(){
    this.discountAmount = subtotal * (getDiscountPercent());
}
public double getDiscountAmount(){
    return this.discountAmount;
}
public void setInvoiceTotal(){
    this.invoiceTotal = subtotal - (getDiscountAmount());
}
public double getInvoiceTotal(){
    return this.invoiceTotal;
}
public void setCustomerType(){
    this.sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            this.sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            this.sCustomerType = "College";
}
public String getCustomerType(){
    return this.sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    sCustomerType = this.getCustomerType();
    discountPercent = this.getDiscountPercent();
    discountAmount = this.getDiscountAmount();
    invoiceTotal = this.getInvoiceTotal();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(subtotal) + "\n"
                   + "Customer type:    " + sCustomerType + "\n"
                   + "Discount percent: " + percent.format(discountPercent)+ "\n"
                   + "Discount amount:  " + currency.format(discountAmount)+ "\n"
                   + "Total:            " + currency.format(invoiceTotal) + "\n");
    return invoice;
}
}

I GOT IT TO WORK, Thanks to you guys! 我努力工作,谢谢大家! Now I understand much more about set and get methods, as well as the this. 现在,我对set和get方法以及相关内容有了更多的了解。 keyword. 关键词。 Here is the working Invoice class: 这是工作发票类:

    import java.text.NumberFormat;

public class Invoice {
private final String customerType;
private double subtotal;
private double discountAmount;
private double discountPercent;
private double invoiceTotal;
private String sCustomerType;

public Invoice(String customerType, double subtotal){
    this.customerType = customerType;
    this.subtotal = subtotal;
}
public void setSubtotal(double subtotal){
    this.subtotal = subtotal;
}
public double getSubtotal(){
    return subtotal;
}
public void setDiscountPercent(double discountPercent){
    this.discountPercent = discountPercent;
}
public double getDiscountPercent(){
    if (customerType.equalsIgnoreCase("r"))
    {
        if (subtotal >= 500)
            discountPercent = .2;
        else if (subtotal >= 250 && subtotal < 500)
            discountPercent =.15;
        else if (subtotal >= 100 && subtotal < 250)
            discountPercent =.1;
        else if (subtotal < 100)
            discountPercent =.0;
    }
    else if (customerType.equalsIgnoreCase("c"))
    {
            discountPercent = .2;
    }
    else
    {
        discountPercent = .05;
    }
    return discountPercent;
}
public void setDiscountAmount(double discountAmount){
    this.discountAmount = discountAmount;
}
public double getDiscountAmount(){
    discountAmount = subtotal * (getDiscountPercent());
    return discountAmount;
}
public void setInvoiceTotal(double invoiceTotal){
    this.invoiceTotal = invoiceTotal;
}
public double getInvoiceTotal(){
    invoiceTotal = subtotal - (getDiscountAmount());
    return invoiceTotal;
}
public void setCustomerType(String sCustomerType){
    this.sCustomerType = sCustomerType;
}
public String getCustomerType(){
    sCustomerType = "Unknown";
        if (customerType.equalsIgnoreCase("r"))
            sCustomerType = "Retail";
        else if (customerType.equalsIgnoreCase("c"))
            sCustomerType = "College";
    return sCustomerType;
}
public String getInvoice(){
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    // Create a string representation of the full invoice and return
    String invoice = ("Subtotal:         " + currency.format(getSubtotal()) + "\n"
                   + "Customer type:    " + getCustomerType() + "\n"
                   + "Discount percent: " + percent.format(getDiscountPercent())+ "\n"
                   + "Discount amount:  " + currency.format(getDiscountAmount())+ "\n"
                   + "Total:            " + currency.format(getInvoiceTotal()) + "\n");
    return invoice;
}
}

Thanks again! 再次感谢!

You are hiding fields with method parameters in a number of places in your code, eg: 您在代码中的许多位置都隐藏了带有方法参数的字段,例如:

public void setDiscountPercent(double discountPercent){
    ...
        if (subtotal >= 500)
            discountPercent = .2;
    ...

Note that you have a field named discountPercent and a method parameter named discountPercent . 请注意,您有一个名为场discountPercent 命名方法参数discountPercent It is the parameter variable that is being modified there, not the field. 在此修改的是参数变量,而不是字段。 Either use this , eg: 使用this ,例如:

public void setDiscountPercent(double discountPercent){
    ...
        if (subtotal >= 500)
            this.discountPercent = .2;
    ...

Or rename your method parameters to not conflict with fields. 或重命名方法参数以不与字段冲突。

You'll have to go through your code and find these, it happens in a few places, eg here's another in setDiscountAmount() : 您必须遍历代码并找到它们,它发生在几个地方,例如,这是setDiscountAmount()的另一个地方:

public void setDiscountAmount(double discountAmount){
    discountAmount = subtotal * (getDiscountPercent());
}

Should be: 应该:

public void setDiscountAmount(double discountAmount){
    this.discountAmount = subtotal * (getDiscountPercent());
}

Also, since you don't actually seem to be using those parameters in your methods anywhere, either a) you shouldn't pass them, or b) you meant to be using them somehow, but you are not. 另外,由于您似乎实际上并没有在任何方法中使用这些参数,因此a)您不应该传递它们,或者b)您本来打算以某种方式使用它们,但实际上并非如此。

Additionally, as MrTi points out in comments, you also don't seem to be calling the setters anywhere. 此外,正如MrTi在评论中指出的那样,您似乎也没有在任何地方打电话给二传手。 You are (attempting to) initialize some of the values in the Invoice constructor, but you're not really finishing the job there. 您正在(尝试)初始化Invoice构造函数中的某些值,但是您并没有真正完成该工作。

As Erwin Bolwidt points out in comments, in general, you seem to be confused about the concepts of "getters" and "setters". 正如Erwin Bolwidt在评论中指出的那样,总的来说,您似乎对“ getters”和“ setters”的概念感到困惑。 In particular, your setters aren't really "setters" - and it doesn't really seem like you actually need them at all to begin with, as your intention seems to be to simply calculate all the values in the constructor then retrieve them later (eg you could just have getters, and perform the calculations either in the getters, or in the constructor). 特别是,您的setter并不是真正的“ setter”-似乎并没有真正真正需要它们,因为您的意图似乎是简单地计算构造函数中的所有值,然后再检索它们(例如,您可能只有吸气剂,并且可以在吸气剂或构造函数中执行计算)。 Check out this question for some good answers and links about the topic. 查看此问题,以获取有关该主题的一些良好答案和链接。 Read through that, and it should give you a better handle on what you're trying to achieve here. 通读此书,它应该可以使您更好地解决此处要达到的目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM