Passing variable values from another method

2020-04-08 01:16发布

I've been working through this problem for several hours, and I've made significant progress (thanks in large part to searching this site and applying tips found in similar questions) but I now seem to be at an impasse. Please take a look through what I have done and either point out where I've gone wrong and provide psuedo code to correct, or point me to a resource that can help me by filling in the gap of my understanding. I really feel as though I'm just missing a tiny detail that will make this topic make sense to me.

The purpose of the application is to add, subtract, multiply, and divide fractions based on user input of 2 numerators and 2 denominators (yes, this is for a course assignment so please don't give source code but rather pointers on where I've gone wrong conceptually). I've broken it down into steps, the first of which is getting the user's input and outputting it back for confirmation.

Method file:

package Fractions;
import java.util.Scanner;

public class FractionValues
{
    // Declare integer class variables for package Fractions
    int fracNum1;
    int fracDenom1;
    int fracNum2;
    int fracDenom2;

    // Obtain four integers from user input and output to console as two fractions
    public static void getFractions(int fracNum1, int fracDenom1, int fracNum2, int fracDenom2)
    {
        Scanner inInt = new Scanner(System.in);

        System.out.println("Enter an integer for the numerator of the first " +
                                    "fraction:  ");
            fracNum1 = inInt.nextInt();

        System.out.println("Enter an integer for the denominator of the first " +
                                    "fraction:  ");
            fracDenom1 = inInt.nextInt();

        System.out.println("Enter an integer for the numerator of the second " +
                                    "fraction:  ");
            fracNum2 = inInt.nextInt();

        System.out.println("Enter an integer for the denominator fo the second " +
                                    "fraction:  ");
            fracDenom2 = inInt.nextInt();
        System.out.println("===================================================" +
                                    "=================");
    }

    // Return values of variables from input for use in other classes
    public int getFracNum1()        {return fracNum1;}
    public int getFracDenom1()      {return fracDenom1;}
    public int getFracNum2()        {return fracNum2;}
    public int getFracDenom2()      {return fracDenom2;}    
}  

main Method file:

package Fractions;
public class TestFractions2
{
    public static void main(String[] args)
    {
        // Call getFractions method to assign variables from user input
        FractionValues newFracNum1 = new FractionValues();
        newFracNum1.getFracNum1();

        FractionValues newFracDenom1 = new FractionValues();
        newFracDenom1.getFracDenom1();

        FractionValues newFracNum2 = new FractionValues();
        newFracNum2.getFracNum2();

        FractionValues newFracDenom2 = new FractionValues();
        newFracDenom2.getFracDenom2();

        System.out.println("You entered " + newFracNum1.getFracNum1() + "/" + newFracDenom1.getFracDenom2() + " and " +
                                     newFracNum2.getFracNum2() + "/" + newFracDenom2.getFracDenom2() + " as your fractions.");
    }
}

At least after some struggles, both files now compile. However, the application doesn't work. This is the output I get:

You entered 0/0 and 0/0 as your fractions.

Once this part works, I'll be adding an if statement prompting the user to respond whether they wish to continue with their choices, or return to the entry prompts.



Based on the valuable feedback below and the constraints of the assignment, I've gotten the following:

package Fractions;
import java.util.Scanner;

public class FractionValues
{
    int fracNum1;
    int fracDenom1;
    int fracNum2;
    int fracDenom2;

    Scanner inInt = new Scanner(System.in);

    // Obtain four integers from user input
    public int getFracNum1()
    {
        System.out.println("Enter an integer for the first numerator:  ");
        return fracNum1 = inInt.nextInt();
    }

    public int getFracDenom1()      
    {
        System.out.println("Enter an integer for the first denominator:  ");
        return fracDenom1   = inInt.nextInt();
    }

    public int getFracNum2()
    {
        System.out.println("Enter an integer for the second numerator:  ");
        return fracNum2     = inInt.nextInt();
    }

    public int getFracDenom2()
    {
        System.out.println("Enter an integer for the second denominator:  ");
        return fracDenom2   = inInt.nextInt();
    }
}

and the main application method:

package Fractions;
public class TestFractions2
{
    public static void main(String[] args)
    {
        // Call FractionValues methods to assign variables from user input
        FractionValues newFracNum1 = new FractionValues(); 
        FractionValues newFracDenom1 = new FractionValues(); 
        FractionValues newFracNum2 = new FractionValues(); 
        FractionValues newFracDenom2 = new FractionValues(); 

        System.out.println("You entered " + newFracNum1.getFracNum1() + "/" + 
                newFracDenom1.getFracDenom2() + " and " + newFracNum2.getFracNum2() +
                "/" + newFracDenom2.getFracDenom2() + " as your fractions."); 
    }
}

Both files compile properly, and I get the following expected output:


Enter an integer for the first numerator:
2 Enter an integer for the second denominator:
5 Enter an integer for the second numerator:
6 Enter an integer for the second denominator:
3 You entered 2/5 and 6/3 as your fractions.


Thank you very much for your help with methods and constructors, and constructive comments on naming conventions. The places your comments led me have very likely taken me from failing my exam to acing it! I've been struggling with this concept for weeks, even with the help of a very patient friend.

3条回答
▲ chillily
2楼-- · 2020-04-08 01:37

your code implicit calls the toString() method of you class GetFractions. Because you haven't overwritten it, its the toString() method from object (the super class). The toString() method from objects returns soemthing like the class name plus a hashcode (see http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#toString%28%29). that's what you see in your output.

you have two possibilities: overwrite toString or change your code like Eng.Fouad mentioned.

查看更多
你好瞎i
3楼-- · 2020-04-08 01:39

The reason why it prints 0-s after you corrected the code is that you actually never call the GetFractions static method, which is NOT a constructor.
Never ever name a method like a constructor, maybe only if it's a static factory method.

Also with the orginal code, you printed the GetFractions objects causing the call of toString you haven't overwritten.
Also notice, that the calls to get... are without any effect since the returned values are not stored anywhere.

查看更多
时光不老,我们不散
4楼-- · 2020-04-08 01:42

There are a few problems with the code. First, the output you see is the product of the default implementation of toString() that is found in Object class (from which all classes including GetFractions ultimately derive). Override this method to return string representation of your instances:

@Override
public String toString() {
  return ...
}

public static void main(String[] args) {
  ...
  System.out.println("..." + newFracNum1 + "...");
}

or instead of passing the instance to System.out.println() pass a result of a member access method call (such methods are known as getters):

public double getSomeValue() {
  return ...
}

public static void main(String[] args) {
  ...
  System.out.println("..." + newFracNum1.getSomeValue() + "...");
}

Note that double and other primitive types will automagically be converted to strings.

Second, your static GetFractions() method modifies its arguments which is ineffective (nobody will see the change since they're passed by value). The method should either modify same-named instance variables of an existing instance and then it should not be static or it should be a factory method creating new instances based on the data provided by the user in which case it would pass the values to a constructor or it should be a constructor itself. Either way, you don't want to modify the method's parameters. Here is the outline of the three solutions:

Non-static method which reads data in from an input stream:

public void fromStream(InputStream inStream) {
  // Read data from inStream into instance variables fracNum1, fracDenom1,...
}

Static factory method:

public static GetFractions fromStream(InputStream inStream) {
  int fracNum1,... ;
  // Read data from inStream into local variables fracNume1, ...
  return new GetFractions(fracNum1, ...);
}

Constructor:

public GetFractions(InputStream inStream) {
  // Read data from inStream to initialize instance variables fracNum1, fracDenom1,...
}

Notice also that passing an InputStream into all these methods affords greater flexibility than hardcoding System.in.

Third, you should reconsider your naming convention. Calling a static method the same as the class, while possible, is generally a bad practice. Also, it's advisable to call classes and objects with noun expressions and methods with verb expressions. This helps to design your classes and makes the code more readable. GetFractions is more suitable as a name of a method rather than a class. Fractions would make for a better class name.

查看更多
登录 后发表回答