Reputation: 3096
So I have this class:
public class x {
ConsoleIO io = new ConsoleIO();
private Board board;
private boolean playing;
public x (String een, String twee) {
this.board = new Board();
if (een.toUpperCase().equals("C")) {
Computer speler1 = new Computer(een);
} else {
Player speler1 = new Player(een);
}
if (twee.toUpperCase().equals("C")) {
this.speler2 = new Computer(twee);
} else {
this.speler2 = new Player(twee);
}
this.playing = true;
}
}
As you can see I want to initialize the variables speler1 & speler2 depending on the input I give. Obviously this doesn't work. I know that I should initialize the variables up front like this:
public class x {
ConsoleIO io = new ConsoleIO();
private Board board;
private boolean playing;
private Player speler1;
private Player speler2;
But then I'm limited to the type Player and I don't want that. Is there a way to do this properly? *Note: Computer is an Extend of Player.
Upvotes: 0
Views: 56
Reputation: 24444
Shouldn't it be something like that:
public class X {
final ConsoleIO io = new ConsoleIO();
private final Board board;
private final Player player1;
private final Player player2;
private boolean playing;
public X(String een, String twee) {
this.board = new Board();
if (een.toUpperCase().equals("C")) {
this.player1 = new Computer();
} else {
this.player1 = new Human(een);
}
if (twee.toUpperCase().equals("C")) {
this.player2 = new Computer();
} else {
this.player2 = new Human(twee);
}
this.playing = true;
}
}
Note:
Both, Human
and Computer
are subclasses of Player
. Move common methods/fields into the Player
base class. If you do it right, it might not be necessary to distinguish between Computer
and Human
later on.
For example, there might be an abstract method move
in the Player
base class that is implemented individually in subclasses: Computer#move
uses an algorithm to calculate the next move; Human#move
asks the human player to input the next move. So if it's turn of player1
, you simply call player1.move()
, regardless of if it's a Human
or Computer
.
Upvotes: 0
Reputation: 1427
Maybe the problem is here:
if (een.toUpperCase().equals("C")) {
Computer speler1 = new Computer(een);//delete here 'Computer'
} else {
Player speler1 = new Player(een);//delete here 'Player'
}
If Computer
extends Player
, why you don't declare a speler1
as Player
before and then initialize it depending on the case?
Player speler1;
...
...
...
if (een.toUpperCase().equals("C")) {
speler1 = new Computer(een);
} else {
speler1 = new Player(een);
}
Upvotes: 0
Reputation: 1186
My answer builds on that of Sabuj:
I would try to let Computer and Player implement a common interface which defines the methods they share. You can then use that interface instead of Object
. I otherwise see no point naming one variable the same way, if you're not going to call the same method no matter what:
public interface Participant {
public void makeMove();
}
public class Player implements Participant {...}
public class Computer implements Participant {...}
This then allows for something like:
Participant p;
if (...) {
p = new Player();
} else {
p = new Computer();
}
...
p.makeMove();
You might be able to avoid some casts this way.
Upvotes: 0
Reputation: 39355
My suggestion would be declaring an Object
:
private Object speler1;
Then inside your if conditions:
speler1 = new Computer(een);
or
speler1 = new Player(een);
Now, when you need to use the speler1, just use a checking like this
// if(speler1 instanceof Computer)
if(speler1 instanceof Player)
player1 = (Player)speler1;
Upvotes: 1