#java #inheritance #arraylist #polymorphism
#java #наследование #список массивов #полиморфизм
Вопрос:
Я пытаюсь реализовать игру в стиле монополии на Java как часть школьного проекта, но я столкнулся с проблемой, которую я не могу решить или, кажется, нахожу ответ на вопрос, который у меня есть. Проблема в том, что я получаю ClassCastException в своем коде, я думаю, я понял, почему я это получаю (изначально я пытался привести type Property
к newPosition
переменной ниже), но теперь мне нужно найти способ реализовать код, чтобы я мог этого избежать.
Проблема в том, что у меня есть суперкласс, Square
который имеет 3 возможных подкласса Property
, Go
и FreeParking
. Я сохраняю свою доску как список массивов, но мне нужно получить доступ к методам, относящимся к Property
объектам, Для расчета арендной платы и т.д. Как я могу получить доступ к этим методам, если при обращении к свойству из ArrayList оно имеет тип Square
.
Заранее приношу извинения, если это не имеет особого смысла.
public abstract class Square {
private String name;
private boolean isAvailable;
private Player owner;
//getters and setters
}
public class Property extends Square{
private String colour;
private int buyHouset;
private int rent1House;
private int rent2House;
private int rent3House;
private int rentHotel;
private int numHouses;
private int rent;
private int price;
//getters and setters
}
public static void takeTurn(Player player, Dice die, ArrayList<Square> board) {
System.out.println(player.getGamertag() "'s turn");
//get value from roll of die
int move = askToRoll();
String gamertag = player.getGamertag();
//if player does not quit continue with turn
if(move > 0) {
//get player current position and add roll of die
int newSpaceIndex = player.getPosition() move;
//if players new position exceeds the array of squares, return to 0 index and add remainder
//add credits for passing Go
//else update position
if (newSpaceIndex > 11) {
player.setPosition(newSpaceIndex - 12);
Go.passGoAction(player);
}else {
player.setPosition(newSpaceIndex);
}
if(player.getPosition() == 1) {
Square newPosition = board.get(player.getPosition());
System.out.println(gamertag " new position " newPosition.getName());
}else if(player.getPosition() == 6) {
FreeParking.freeParkingAction();
} else {
Square newPosition = board.get(player.getPosition());
System.out.println("____________________");
System.out.println("Land on " newPosition.getName());
if(newPosition.getOwner() != null) {
Player owner = newPosition.getOwner();
/* *****THIS IS WHERE THE ERROR IS STEMING FROM*****
*THE newPosition.getRent() method can not be accessed as newPosition
*is defines as Square
*/
System.out.println(owner.getGamertag() " demands you pay " newPosition.getRent() " credits!");
}else {
System.out.println("What would you like to do now? ...n"
"1. Buy propertyn"
"2. End turn");
int input = in.nextInt();
boolean valid = false;
do {
switch(input) {
case 1:
System.out.println("You now own controlling stock of " newPosition.getName());
player.setOwnsProperty(newPosition);
newPosition.setOwner(player);
valid = true;
break;
case 2:
System.out.println("Ending turn");
valid=true;
break;
default:
System.out.println("Invalid input, please select one of the options 1-2");
valid = false;
break;
}
}while(!valid);
}
}
}
System.out.println("END TURN: " player);
System.out.println();
}
Ответ №1:
Если вы знаете, что определенный квадрат является свойством, приведите его к соответствующему типу.
Property newPosition = (Property)board.get(player.getPosition());
Редактировать: В будущем вы также можете рассмотреть возможность переноса логики, которая соответствует определенному типу Square, в подкласс. Другими словами, что-то вроде square.process(player)
, где Property, Go и FreeParking каждый реализует process(player)
метод с соответствующей логикой. Это относится к более подробным концепциям объектно-ориентированного проектирования и может быть не актуально для вас прямо сейчас.
Комментарии:
1. Спасибо за ваш ответ, я пытался привести этот конкретный квадрат, как вы описали, но это вызывало исключение ClassCastException. Я думал, это потому, что я пытался преобразовать квадрат в свойство?
2. Каково точное сообщение об исключении и трассировка стека?
3. Исключение в потоке «main» java.lang. Исключение ClassCastException: монополия. Go нельзя преобразовать в Monopoly. Свойство … ах. тогда, очевидно, в этом проблема
Ответ №2:
Я надеюсь, что этот фрагмент поможет вам понять концепцию
public static void main(String[] args) {
Square newPosition = new Property();
if (newPosition instanceof Property) {
System.out.println("newPosition cast as Property");
Property newPositionAsProperty = ((Property) newPosition);
int newRent = newPositionAsProperty.getRent();
// or
newRent = ((Property) newPosition).getRent();
}
// To understand better
if (newPosition instanceof Square) {
System.out.println("newPosition instanceof Square");
((Square)newPosition).getName();
}
if (Square.class.isAssignableFrom(Property.class)) {
System.out.println("Square.class.isAssignableFrom(Property.class)");
((Square)newPosition).getName();
}
if (Property.class.isInstance(newPosition)) {
System.out.println("Property.class.isInstance(newPosition)");
((Property)newPosition).getName();
}
if (Square.class.isInstance(newPosition)) {
System.out.println("Square.class.isInstance(newPosition)");
((Square)newPosition).getName();
}
}
Результат:
newPosition cast as Property
newPosition instanceof Square
Square.class.isAssignableFrom(Property.class)
Property.class.isInstance(newPosition)
Square.class.isInstance(newPosition)