Проблема переопределения tostring

Я хочу переопределить метод toString класса Ship в методе toString класса CargoShip, чтобы консоль не печатала год постройки корабля. Я пытался сделать это, но он все еще печатает год. Я не уверен, неправильно ли я кодирую переопределение или проблема связана с тем, как метод вызывается в классе ShipDemo.

Класс корабля:

public class Ship {
    public String shipName;
    public String yearBuilt;

    public Ship() {
    }

    public Ship(String name, String year) {
        shipName = name;
        yearBuilt = year;
    }

    public void setShipName(String name) {
        shipName = name;
    }

    public void setYearBuilt(String year) {
        yearBuilt = year;
    }

    public String getShipName() {
        return shipName;
    }

    public String getYearBuilt() {
        return yearBuilt;
    }

    public String toString() {
        //return toString() + " Name: " + shipName
        //+ "\n Year Built: " + yearBuilt;
        String str;
        str = " Name: " + shipName + "\n Year Built: " + yearBuilt;

        return str;
    }
}

Класс грузового корабля:

public class CargoShip extends Ship {
    public int capacity;

    public CargoShip() {
    }

    public CargoShip(int maxCap, String name, String year) {
        super(name, year);
        capacity = maxCap;
    }

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int cap) {
        cap = capacity;
    }

    public String toString() {
        return super.toString() + " Name: " + getShipName()
                + " Tonnage Capacity: " + getCapacity();
    }
}

Класс ShipDemo:

public class ShipDemo {
    public static void main(String[] args) {
        // Array Reference
        Ship[] shiptest = new Ship[3];

        // Elements in array set to ship type
        shiptest[0] = new Ship();
        shiptest[1] = new CargoShip();
        shiptest[2] = new CruiseShip();

        // Ship 1
        shiptest[0].setShipName("Manitou ");
        shiptest[0].setYearBuilt("1936 ");

        // Ship 2 ; Cargoship
        shiptest[1] = new CargoShip(13632, "SS Edmund Fitzgerald", "1958");

        // Ship 3 ; Cruiseship
        shiptest[2] = new CruiseShip(2620, "RMS Queen Mary 2", "2004");

        // loop to print out all ship info
        for (int i = 0; i < shiptest.length; i++) {
            // Output
            System.out.println("Ship " + i + " " + shiptest[i]);
        }
    }
}

person user2016569    schedule 19.02.2013    source источник
comment
Но вы включили тело Ships версии toString в свою CargoShip реализацию. Он работает именно так, как вы его закодировали.   -  person Perception    schedule 20.02.2013
comment
Как так? Год не указан.   -  person user2016569    schedule 20.02.2013
comment
Потому что вы вызвали super.toString(), который вызовет метод toString для суперкласса класса CargoShip, который оказывается ... Ship.   -  person Perception    schedule 20.02.2013


Ответы (1)


В CargoShip у вас есть следующее:

public String toString()
{       
    return super.toString() + " Name: " + getShipName() + " Tonnage Capacity: "      + 
    getCapacity();    
}

Вызывая super.toString(), вы фактически вызываете метод toString() родительского класса, который включает печать года. Вы должны удалить вызов этого метода и изменить возвращаемую строку, чтобы она включала только ту информацию, которую вы хотите отобразить.

Переопределение родительского метода означает предоставление метода с тем же именем, списком аргументов, типом возвращаемого значения и видимостью, возможно, с другой реализацией (тело метода). Вам не нужно вызывать super, чтобы он считался переопределяющим.

Вы можете захотеть иметь что-то вроде этого в CargoShip:

public String toString()
{       
    return " Name: " + getShipName() + " Tonnage Capacity: " + getCapacity();    
}
person Sotirios Delimanolis    schedule 19.02.2013
comment
В моих указаниях говорится, что мне нужен метод toString, который переопределяет метод toString в базовом классе. - person user2016569; 20.02.2013
comment
Вы уже делаете это, определяя свой собственный метод toString() в CargoShip, который расширяет Ship. Вам не нужно вызывать родительский, чтобы переопределить его. Просто наличие метода с тем же определением метода переопределяет. - person Sotirios Delimanolis; 20.02.2013
comment
Если я просто вызову toString из CargoShip без super, я должен получить ошибку запуска. - person user2016569; 20.02.2013
comment
Если я запускаю его без super, я получаю эту ошибку Исключение в потоке main java.lang.StackOverflowError - person user2016569; 20.02.2013
comment
Это потому, что вы все еще вызываете toString() рекурсивно, что вызывает бесконечный цикл и заставляет java исчерпать память. Полностью исключите вызов этого метода. Посмотрите на мой отредактированный ответ. - person Sotirios Delimanolis; 20.02.2013
comment
Спасибо вам за помощь. Думаю, мне было трудно понять, что считается переопределением. - person user2016569; 20.02.2013