【问题标题】:Trouble instantiating an object within an if block在 if 块中实例化对象时遇到问题
【发布时间】:2013-08-11 05:07:49
【问题描述】:

我编写了一个程序,用户可以在其中选择玩两种游戏:猪或蛇。我尝试在我的 main 方法中使用以下代码来创建合适的游戏:

if (gameType == 'p')
    PigGame game = new PigGame();
else
    SnakeGame game = new SnakeGame();

我的编译器指向第二行并给出错误:not a statement

我已经设法通过编写一个抽象类“Game”来解决这个问题,然后制作它的 PigGame 和 SnakeGame 子类:

Game game;
if (gameType == 'p')
    game = new PigGame();
else
    game = new SnakeGame();

但我不明白为什么第一个构造不起作用。 (我正准备教授一门高中编程课程,但我是 Java 和 OOP 的新手,所以我可以利用你能提供的任何见解。)

【问题讨论】:

  • 您是否导入了 PigGame 和 SnakeGame 文件?另外,尽量不要将它们命名为相同的变量名……尝试使用 pigGame 或 snakeGame 作为变量名……
  • 看看下面的内容,对java中块作用域的概念有更深入的理解:books.google.com/… 特别注意图中指示变量“出”的地方范围外”。希望对您有所帮助。

标签: java scope


【解决方案1】:

问题是game的作用域在if和else里面

if (gameType == 'p')
    PigGame game = new PigGame();
else
    SnakeGame game = new SnakeGame();

所以你不能在其他任何地方使用它,这就是你的第二段代码有效的原因。

【讨论】:

  • 是的,这是有道理的。我被编译器错误愚弄了。 PigGame game = new PigGame(); 似乎是一个声明。当我再次尝试使用游戏时,我会预料到会出现错误。
  • @user2625004 我建议您在课堂上使用始终使用带有forif 语句的大括号的编码标准。它可以帮助新程序员(或新 Java 程序员)识别和捕捉此类问题,并建立一个良好的变量范围心理模型。
【解决方案2】:

"PigGame 游戏 = 新 PigGame();"是声明,不是声明。 if 需要声明,而不是声明。您可以创建一个包含它的语句块:

{
    PigGame game = new PigGame();
}

这在语法上是正确的。它仍然毫无意义,因为游戏将是语句块的本地。您需要在更广泛的范围内声明游戏。

【讨论】:

    【解决方案3】:

    其实是一个很重要的问题

    if (gameType == 'p')
        PigGame game = new PigGame();
    else
        SnakeGame game = new SnakeGame();
    

    仅由于 Java 语法不能编译,该语法指出变量声明不是声明。事实上,可以想象一段代码,他实际上并不需要这个变量“游戏”,而只是想在 if 语句中运行构造函数。

    if (gameType == 'p')
        new PigGame();
    else
        new SnakeGame();
    

    这将编译

    if (gameType == 'p'){
        PigGame game = new PigGame();
    }else{
        SnakeGame game = new SnakeGame();
    }
    

    这也会编译

    在这两种情况下很自然 - 我们无法访问括号外的变量,但仍然拒绝用户像这样对其进行编码

    if (gameType == 'p')
        PigGame game = new PigGame();
    else
        SnakeGame game = new SnakeGame();
    

    有点武断,AFAIK 旨在“确保”用户知道他在做什么。一般来说 - 变量的分数是由它的声明定义的括号括起来所以如果你写

    {
    Integer x=3;
    System.out.println(x); //this works
    }
    System.out.println(x); //but this does not
    

    同样的事情也适用于这里——你可以在 if 语句中声明一个 Game 对象,但在它之外它不会被 game 变量访问。但这取决于你的代码,你可以有类似的东西

    public class Game{
       public static Game lastCreatedGame;
       public Game(){
        lastCreatedGame=this;
       }
    }
    

    然后,运行

    if (gameType == 'p')
        new PigGame();
    else
        new SnakeGame();
    

    仍然会让你通过Game.lastCreatedGame 字段访问游戏

    【讨论】:

      【解决方案4】:

      这就是我要求所有新手不要跳过花括号的原因,因为它使范围更加清晰。

      当你制作时

      if (gameType == 'p')
          PigGame game = new PigGame();
      else
          SnakeGame game = new SnakeGame();
      

      进入

      if (gameType == 'p') {
          PigGame game = new PigGame();
      }
      else {
          SnakeGame game = new SnakeGame();
      }
      

      范围变得更加清晰,两者都

      PigGame game = new PigGame();SnakeGame game = new SnakeGame();

      仅存在于它们各自的块内(即)各自的花括号内,

      这意味着您不能在各自块之外的任何地方使用game,编译器会看到这一点并抛出错误来帮助您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多