Java方法返回不正确的值

时间:2014-03-29 00:36:34

标签: java

我正在努力学习在Java中正确编写方法。我看了很多例子,看不出我做错了什么。我有一个名为InvoiceApp的主类,它使用一个名为Validator的类来筛选输入,然后使用一个名为Invoice的类来处理用户输入。运行InvoiceApp时,用户输入“r”或“c”作为“客户类型”,输入“小计”的双精度值。该应用程序创建Invoice类的对象以使用getInvoice()方法,该方法返回格式化的发票。 返回格式化的发票,但字符串的NULL值和所有数字的ZEROES(用户在第一位输入的除外)。 Invoice类显然没有为变量赋值。我已经做了很多很多种不同的方法,但却无法使用。

谁能看到我做错了什么?这是我的代码:

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();
    }
} 
}

发票类:

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;
}
}

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;
}
}

感谢任何可以提供帮助的人


谢谢大家。我从setter方法中删除了参数并添加了它。对施工人员。显然,有两个主要方面我很困惑:

  1. 设定方法中应该包含哪些参数?我试图插入set方法实际上使用的变量,但这也不起作用。

  2. 我认为get方法只是用于返回set方法生成的值。由于setter都是无效的,因此无法直接使用。我见过的工作实例是相似的(但它们实际上是有效的)。

  3. 以下是我在Invoice课程中所做的更改。

        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;
    }
    }
    

    我很乐意工作,谢谢你们!现在我对set和get方法有了更多的了解,以及这个方法。关键词。 这是工作发票类:

        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;
    }
    }
    

    再次感谢!

1 个答案:

答案 0 :(得分:2)

您在代码中的许多位置隐藏了带有方法参数的字段,例如:

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

请注意,您有一个名为discountPercent 的字段和一个名为discountPercent的方法参数。它是在那里修改的参数变量,而不是字段。使用this,例如:

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

或者重命名方法参数以与字段不冲突。

你必须仔细阅读你的代码才能找到这些代码,它会发生在一些地方,例如:这是setDiscountAmount()中的另一个:

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

应该是:

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

另外,既然你实际上似乎没有在你的方法中使用这些参数,或者a)你不应该传递它们,或者b)你打算以某种方式使用它们,但你不是。

另外,正如MrTi在评论中指出的那样,你似乎也没有在任何地方打电话给安装人员。你是(试图)初始化Invoice构造函数中的一些值,但你并没有真正完成那里的工作。

正如Erwin Bolwidt在评论中指出的那样,总的来说,你似乎对“吸气者”和“定位者”的概念感到困惑。特别是,你的setter并不是真正的“setter” - 而且你似乎并不真正需要它们,因为你的意图似乎是简单地计算构造函数中的所有值然后稍后检索它们(例如,你可以只有getter,并在getter或构造函数中执行计算)。查看this question以获取有关该主题的一些好答案和链接。仔细阅读,它应该可以让你更好地处理你想要实现的目标。