【问题标题】:Passing variable values from another method从另一个方法传递变量值
【发布时间】:2012-01-07 01:42:43
【问题描述】:

我已经解决了这个问题几个小时,并且我已经取得了重大进展(很大程度上要感谢搜索此站点并应用在类似问题中找到的提示),但我现在似乎陷入了僵局。请看一下我所做的事情,或者指出我哪里出错并提供伪代码来纠正,或者指出我可以通过填补我的理解空白来帮助我的资源。我真的觉得好像我只是错过了一个让这个话题对我有意义的小细节。

应用程序的目的是根据用户输入的 2 个分子和 2 个分母来加、减、乘和除分数(是的,这是一个课程作业,所以请不要提供源代码,而是指点我在概念上出错的地方)。我已将其分解为多个步骤,其中第一步是获取用户的输入并将其输出回来以供确认。

方法文件:

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

主方法文件:

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.");
    }
}

至少经过一番努力,这两个文件现在都可以编译了。但是,该应用程序不起作用。这是我得到的输出:

您输入了 0/0 和 0/0 作为分数。

一旦这部分工作,我将添加一个 if 语句,提示用户响应他们是否希望继续他们的选择,或者返回到输入提示。



根据下面的宝贵反馈和作业的限制,我得到了以下信息:

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

及主要应用方法:

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."); 
    }
}

两个文件都正确编译,我得到以下预期输出:


为第一个分子输入一个整数:
2 输入第二个分母的整数:
5 为第二个分子输入一个整数:
6 输入第二个分母的整数:
3 您输入了 2/5 和 6/3 作为分数。


非常感谢您在方法和构造函数方面的帮助,以及在命名约定方面的建设性 cmets。您的 cmets 带领我去的地方很可能使我从考试不及格变成了高分!几个星期以来,我一直在为这个概念苦苦挣扎,即使是在一位非常耐心朋友的帮助下。

【问题讨论】:

  • 我认为拥有一个带有分子和分母的 Fraction 或 Rational 类以及可能的 I/O 例程会极大地简化您的代码(可能还有您的想法)。
  • 我的意思是,考虑重命名类,类名应该是名词...我累了...

标签: java variables methods parameter-passing


【解决方案1】:

代码存在一些问题。首先,您看到的输出是在Object 类中找到的toString() 的默认实现的产物(包括GetFractions 在内的所有类最终派生自该类)。覆盖此方法以返回实例的字符串表示形式:

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

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

或者不将实例传递给System.out.println(),而是传递成员访问方法调用的结果(此类方法称为getter):

public double getSomeValue() {
  return ...
}

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

请注意,double 和其他原始类型将自动转换为字符串。

其次,您的静态 GetFractions() 方法修改了无效的参数(没有人会看到更改,因为它们是按值传递的)。该方法应该修改现有实例的同名实例变量,然后它不应该是静态的,或者它应该是根据用户提供的数据创建新实例的工厂方法,在这种情况下,它将值传递给构造函数或者它应该是一个构造函数本身。无论哪种方式,您都不想修改方法的参数。以下是三种解决方案的概要:

从输入流中读取数据的非静态方法:

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

静态工厂方法:

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

构造函数:

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

另请注意,将InputStream 传递给所有这些方法比硬编码System.in 提供更大的灵活性。

第三,您应该重新考虑您的命名约定。尽管可能,但调用与类相同的静态方法通常是一种不好的做法。此外,建议用名词表达式调用类和对象,用动词表达式调用方法。这有助于设计您的类并使代码更具可读性。 GetFractions 更适合作为方法名而不是类名。 Fractions 会是一个更好的类名。

【讨论】:

  • 绝妙的例子!我肯定对方法的句法感到困惑。
【解决方案2】:

您的代码隐式调用 GetFractions 类的 toString() 方法。因为您没有覆盖它,所以它是来自对象(超类)的 toString() 方法。对象的 toString() 方法返回类名加上哈希码(参见http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#toString%28%29)。这就是您在输出中看到的内容。

您有两种可能性:覆盖 toString 或更改您的代码,如 Eng.Fouad 提到的。

【讨论】:

  • 非常感谢您提供资源!它使阅读变得有趣,我已经记下了当我的课程涉及这些主题时重新审视它!
【解决方案3】:

在您更正代码后它打印 0-s 的原因是您实际上从未调用过 GetFractions 静态方法,它不是构造函数。
永远不要将方法命名为构造函数,也许只有当它是静态工厂方法时。

同样使用原始代码,您打印了 GetFractions 对象,导致调用 toString 您没有被覆盖。
另请注意,对 get... 的调用没有任何效果,因为返回的值没有存储在任何地方。

【讨论】:

  • 您在构造函数与静态方法上的 cmets 使我走上了一条巨大的帮助之路。我想我终于掌握了整个方法/构造函数的概念。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 2012-09-12
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多