【问题标题】:Beginner Java Scope Issue [duplicate]初学者 Java 范围问题 [重复]
【发布时间】:2015-08-09 00:03:06
【问题描述】:

我是编程新手,似乎遇到了变量、类等何时可以引用和不能引用的问题。下面是一个例子,希望你们能解决具体问题,但也能帮助我更广泛地理解它,这样我就不会一次又一次地遇到它。

要尽量避免发布一堆代码,请注意定义了一个 Question 类以及 setText、setAnswer、checkAnswer 和 display 方法都在其他地方定义(全部公开)。

相关代码如下,我有两个问题:

  1. 为什么presentQuestion()方法中不能识别变量first
  2. 最后,为什么我不能先调用方法checkAnswer(),即为什么我不能直接调用first.checkAnswer(response);?为什么我必须在一个新变量中定义它:boolean outcome = first.checkAnswer(response);

代码:

/**
 * This program shows a simple quiz with two questions.
 */

public class QuestionDemo {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        Question first = new Question();
        first.setText("Who was the inventor of Java?");
        first.setAnswer("James Gosling");

        Question second = new Question();
        second.setText("Who was the founder of Udacity?");
        second.setAnswer("Sebastian Thrun");

        int score = 0;
        score = score + presentQuestion(first, in);
        // Present the second question
        score = score + presentQuestion(second, in);
        System.out.println("Your score: " + score);
    }

    /**
     * Presents a question to the user and obtains a response.
     * @param q the question to present
     * @param in the scanner from which to read the user input
     * @return the score (1 if correct, 0 if incorrect);
     */
    public static int presentQuestion(Question q, Scanner in) {
        // Display the first question
        first.display();
        System.out.println("Your answer:");
        String response = in.nextLine();
        // Check whether the response was correct
        // If so, print "true" and return 1
        // Otherwise, print "false" and return 0
        boolean outcome = first.checkAnswer(response);
        System.out.println(outcome);
        if (outcome) {
            return 1;
        }
        else {
            return 0;
        }
    }
}

【问题讨论】:

    标签: java scope


    【解决方案1】:

    不能在presentQuestion 中使用变量first 的原因是它在main 中定义,因此在main 之外不可见。这不正是您给presentQuestion 提供Question q 参数的原因吗?

    在我看来,这就是你想要做的:

    public static int presentQuestion(Question q, Scanner in)
    {
        // Display the first question
        q.display();
        System.out.println("Your answer:");
        String response = in.nextLine();
        // Check whether the response was correct
        // If so, print "true" and return 1
        // Otherwise, print "false" and return 0
        boolean outcome = q.checkAnswer(response);
        System.out.println(outcome);
        if (outcome) {
            return 1;
        } else {
            return 0;
        }
    }
    

    请注意,对first 的引用已替换为对q 的引用。

    为了弄清楚我想你的困惑可能在于,想象如果presentQuestion 是从main 以外的其他方法调用的,在这种情况下根本不会声明first 变量。那么presentQuestion 内部对first 的引用会发生什么,现在根本没有引用任何内容?这就是为什么您需要显式传递所需数据作为参数的原因。不同的方法是独立的代码块,即使它们碰巧相互调用,你也不能在它们之间混合变量引用。

    关于问题2,不使用outcome变量,直接检查if(q.checkAnswer(response))应该确实没有问题。当first 再次无法识别时,我猜你只是被编译器发出的错误弄糊涂了。

    【讨论】:

    • 非常感谢 Dolda(以及其他所有回答的人)。我真的没有正确理解参数,这确实是我理解的一大进步。代码现在可以工作了,我真的明白为什么了,再次感谢
    【解决方案2】:
    1. first 是一个局部变量,这意味着它只能在定义它的方法内部访问。
    2. 您不必在使用之前将checkAnswer() 的结果放入布尔值中。实际上,if (checkAnswer(response)) { ... } 是有效的。

    【讨论】:

      【解决方案3】:

      presentQuestion 将问题作为参数。在main 中,您在第一个问题上调用它,然后在第二个问题上调用它;看起来意图是您在第一个问题上使用presentQuestion,然后在第二个问题上使用。到目前为止,一切顺利。

      问题在于,在presentQuestion 中,您在参数列表中将问题(可能是第一个或第二个问题)称为q。您需要做的就是在方法的其余部分使用q 而不是first

      【讨论】:

        【解决方案4】:

        当我刚接触编程时,我也遇到过这个问题!然后我发现它非常很简单。

        对于您的第一个问题,firstmain 方法中声明,您想在presentQuestion 方法中使用它。但是presentQuestionmain 是不同的方法!所以你无法在presentQuestion 中访问first。如您所见,presentQuestion 方法中有一个Question-typed 参数。这就像你告诉first,“过来,伙计!然后把你的名字改成q。”当您将参数 first 传递给 presentQuestion 时,

        presentQuestion (first, in);
        

        first 来到pressentQuestion 方法,其名称为q。所以你应该在presentQuestion方法中使用q而不是first

        现在是第二个问题,不需要在这种情况下使用变量。但是为了提高效率,使用布尔变量来存储checkAnswer 的结果。让我们想象一下如果不使用布尔变量会发生什么。

        System.out.println(q.checkAnswer(response));
            if (q.checkAnswer(response)) {
                return 1;
            } else {
                return 0;
            }
        

        看到了吗?你打电话给q.checkAnswer两次!这会减慢您的程序,因此您应该使用布尔变量。

        【讨论】:

          猜你喜欢
          • 2014-05-11
          • 1970-01-01
          • 2021-01-28
          • 2013-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-25
          相关资源
          最近更新 更多