Списки массивов и полиморфизм в Java

#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)