简体   繁体   中英

Java method returning incorrect values

I'm struggling learning to properly code methods in 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. When InvoiceApp is run, the user inputs either 'r' or 'c' as the Customer Type, and a double value for "subtotal". The app creates an object of the Invoice class to use the getInvoice() method, which returns a formatted invoice. 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). 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:

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:

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. 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. 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. 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 . It is the parameter variable that is being modified there, not the field. Either use this , eg:

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() :

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.

Additionally, as MrTi points out in comments, you also don't seem to be calling the setters anywhere. You are (attempting to) initialize some of the values in the Invoice constructor, but you're not really finishing the job there.

As Erwin Bolwidt points out in comments, in general, you seem to be confused about the concepts of "getters" and "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). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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