user2625004
user2625004

Reputation: 63

Trouble instantiating an object within an if block

I've written a program where users can choose between two games to play: Pig or Snake. I tried to use the following code within my main method to create the appropriate kind of game:

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

My compiler points to the second line and gives the error: not a statement

I have managed to fix the problem by writing an abstract class "Game" and then making PigGame and SnakeGame subclasses of it:

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

But I don't understand why the first construct didn't work. (I'm preparing to teach a high school programming course, but I'm new to Java and OOP so I can use any insights you can provide.)

Upvotes: 4

Views: 115

Answers (4)

Gautam
Gautam

Reputation: 7958

This is the reason I request all newbies to not skip the curly braces because It gives a lot of clarity on scope.

When you make

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

into

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

the scope becomes clearer, both

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

only exist within their respective blocks (i.e) within their respective curly braces,

so that means you cannot use game anywhere outside of their respective blocks, the compiler sees this and throws an error to help you out.

Upvotes: 1

lejlot
lejlot

Reputation: 66805

It is actually a quite important issue

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

does not compile only due to the Java grammar, which states that a variable declaration is not a statemant. In fact one could imagine a code, where he actually does not need this variable "game" and simply want to run constructors in if statement.

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

and this will compile

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

this will also compile

Naturally in both cases - we do not have access to the variable outside the brackets, yet still, denying user to code it like

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

is a bit arbitrary, and AFAIK aimed at making "sure" that user knows what he is doing. In general - score of variable is defined by its declaration surrounding brackets so if you write

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

and the same thing applies here - you can declare a Game object inside an if statement, but it would not be accseeible outside of it by the game variable. But it depends on your code, You could have something like

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

then, running

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

would still give you access to the game, by Game.lastCreatedGame field

Upvotes: 1

Patricia Shanahan
Patricia Shanahan

Reputation: 26185

"PigGame game = new PigGame();" is a declaration, not a statement. An if requires a statement, not a declaration. You could create a statement block containing it:

{
    PigGame game = new PigGame();
}

That would be syntactically correct. It would still be pointless, because game would be local to the statement block. You need game to be declared with a wider scope.

Upvotes: 2

jsedano
jsedano

Reputation: 4216

The problem is that the scope of game is inside the if and the else

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

So you can't use it anywhere else, that's why your second piece of code works.

Upvotes: 3

Related Questions