【问题标题】:How to get values from another class in Java?如何从Java中的另一个类获取值?
【发布时间】:2019-07-20 13:18:08
【问题描述】:

我刚开始学习语言,但一开始就卡住了。我正在编写一个非常简单的计算器,用户必须在其中一行输入值。我按顺序获取这些值并将它们保存到我操作的变量中。为了保存值和执行操作,我有一个单独的类,叫做 Сalс。

package com.company;
import java.util.Scanner;


public class Main {

    public static void main(String[] args) {
        System.out.print("Enter expression:");
        Calc calc = new Calc();
        System.out.printf("Result is:" + calc);
    }
}

class Calc {
    Scanner scanner = new Scanner(System.in);
    int num1 = scanner.nextInt();
    String operation = scanner.next();
    int num2 = scanner.nextInt();

    public int calc(int num1, int num2, String operation){
        int result;
        switch (operation){
            case "+": result = num1+num2; break;
            case "-": result = num1-num2; break;
            case "*": result = num1*num2; break;
            case "/": result = num1/num2; break;
            default: System.out.println("The operation is not recognized. Repeat entry.");
                result = calc(num1, num2, operation);
        }
        return result;
    }
}

我尝试直接调用结果:

calc(result)
calc.calc(result)

但得到“无法解析符号”结果。

在主类中,我希望得到已经计算好的值。请帮帮我。

【问题讨论】:

  • 您必须在 calc 对象上使用参数调用方法 - calc.calc(1, 2, "+")
  • 我有一个扫描仪,它应该给我用户将输入的值。程序在完成的结果应该发送到主类的 calc 方法中替换它们(值)。我希望输出有一个已经计算好的结果,而不需要代码提前指定数字和运算符。

标签: java class oop object


【解决方案1】:

为此使用“OOP”或类确实没有意义,但通过简单的修改,您至少可以让您的代码工作:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        System.out.print("Enter expression:");
        Calc calc = new Calc();
        System.out.printf("Result is: " + calc.calc());
    }
}

class Calc {
    public int calc(){
        Scanner scanner = new Scanner(System.in);
        int num1 = scanner.nextInt();
        String operation = scanner.next();
        int num2 = scanner.nextInt();

        int result = 0;
        switch (operation){
            case "+": result = num1+num2; break;
            case "-": result = num1-num2; break;
            case "*": result = num1*num2; break;
            case "/": result = num1/num2; break;
            default:
                System.out.println("The operation is not recognized. Repeat entry.");
                calc();
        }
        scanner.close();
        return result;
    }
}

请注意,在您的原始代码中,您从未在 main 方法中调用过 calc() 方法。

【讨论】:

    【解决方案2】:

    您定义了将用户输入作为Calc 类的实例字段的逻辑 - 我认为这不是您想要的。您应该将此逻辑移至您的 main 方法。现在,当Calc 类的对象被初始化时,用户将被要求输入,我认为这真的很不典型——它应该发生在某个方法的主体内。

    此外,您在 Calc 类中创建了一个方法 calc,因此您应该调用此方法并在那里传递相关参数。

    当不支持操作时,switch statemnt 中的默认标签代码也会导致无限递归,因此您应该找到另一种再次要求用户输入的方式(loop 是关键字)-暂时我选择抛出一个异常-但你应该自己想办法处理它。修复后的代码如下所示:

    public class Main {
    
        public static void main(String[] args) {
            System.out.println("Enter expression:");
            Scanner scanner = new Scanner(System.in);
    
            int num1 = scanner.nextInt();
            String operation = scanner.next();
            int num2 = scanner.nextInt();
    
            Calc calc = new Calc();
            System.out.printf("Result is:" + calc.calc(num1, num2, operation));
        }
    }
    
    class Calc {
    
        public int calc(int num1, int num2, String operation){
            int result;
            switch (operation){
                case "+": result = num1+num2; break;
                case "-": result = num1-num2; break;
                case "*": result = num1*num2; break;
                case "/": result = num1/num2; break;
                default: System.out.println("The operation is not recognized. Repeat entry.");
                    throw new IllegalArgumentException("Operation not supported");
            }
            return result;
        }
    }
    

    【讨论】:

      【解决方案3】:

      这里有很多事情要讨论。让我们从result 变量开始。在这里,一切都与范围有关。变量result 是一个局部变量,因此只能从声明点到周围方法的末尾可见。这意味着您可以在 main 方法中编写类似的内容:

      final int result = calc.calc(num1, num2, operation);
      System.out.println(System.out.printf("Result is:" + result);
      

      但这会让您在调用calc.calc(...) 之前阅读num1num2operation,这是您想通过创建类calc 来防止的问题。您在构造 Calc 类的对象时读取这些值。我强烈建议不要使用这种方法并在单独的方法中卸载值的读取,而是在Calc 中编写一个构造函数,它接受两个int-values 和一个String-value。这是一个粗略的草图:

      public class Cals {
          private final int num1;
          private final int num2;
          private final String operation;
      
          public Calc(final int num1, final int num2, final String operation) {
              this.num1 = num1;
              this.num2 = num2;
              this.operation = operation;
          }
      
          public int calc() {
              int result;
              switch (operation){
                  case "+":
                      result = num1 + num2; 
                      break;
                  case "-": 
                      result = num1 - num2; 
                      break;
                  case "*":
                      result = num1 * num2; 
                      break;
                  case "/":
                      result = num1 / num2;
                      break;
                  default: 
                      System.out.println("The operation is not recognized. Aborting.");
                      return 0;
              }
              return result;
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              ...
              final Calc calc = readValuesFromConsoleAndConstructCalcObject();
              ...
              System.out.println(calc.calc());
          }
      
          public static Calc readValuesFromConsoleAndConstructCalcObject() {
              final Scanner scanner = new Scanner(System.in);
              System.out.print("Enter 1st number: ");
              final int num1 = scanner.nextInt();
      
              System.out.print("Enter operation: ");
              final String operation = scanner.next();
      
              System.out.print("Enter 2nd number: ");
              final int num2 = scanner.nextInt();
      
              return new Calc(num1, num2, operation);
          }
      }
      

      您可能已经注意到,我还从方法calc() 中删除了参数并改用对象属性。

      我还消除了switchcalc 内的default 分支中的递归调用,以防止无限递归。


      对您的代码的一些评论:

      • 对象属性(或字段,或属性,或者您如何命名)应始终设置为private,并且只能通过mutators 访问。
      • 始终在分号后换行。总是。
      • 保持一致。你的代码风格。在二元运算符(===+-*/,...)的两侧设置空白或根本不设置空白。您正在混合两种风格。
      • 出于学习目的,可以在String 上创建switch,在生产中这可能是性能问题。我建议使用Enum 来表示允许的数学运算。
      • 此外,当出现问题时返回0(或者在这种情况下实际上是任何值)是一种气味。我建议throw an Exception,在这种情况下我很想抛出IllegalArgumentException

      【讨论】:

        猜你喜欢
        • 2014-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-12
        • 2021-10-19
        相关资源
        最近更新 更多