Наследование Java заставляет меня делать вещи, которые я не хочу, когда вызывается super () - PullRequest
3 голосов
/ 29 ноября 2010

Я читаю официальные руководства по Java на веб-сайте Oracle, и мне не нравится то, что я вижу при экспериментировании с Inheritance.

Я создал класс Bicycle и класс MountainBike, расширяющий Bicycle.MountainBike вынужден вызывать super () для конструктора Bicycle из его собственного конструктора, но вот что происходит:

A Bicycle has been created.
A Bicycle has been created.
A MountainBike has been created.

Когда классы выглядят так (фрагмент):

public Bicycle(int speed) {
 this.speed = speed;
 System.out.println("A Bicycle has been created.");
}

public MountainBike(int seatHeight, int speed) {
 super(speed);
 this.setSeatHeight(seatHeight);
 System.out.println("A MountainBike has been created.");
}

Это не желаемое поведение.

  1. Является ли это общим недостатком наследования?
  2. Что вы делаете в этом случае?

Ответы [ 2 ]

4 голосов
/ 29 ноября 2010

В чем недостаток?Класс MountainBike вызывает конструктор Bicycle, и поэтому вы увидите, что результат "A Bicycle был создан".прежде чем вы увидите «Горный велосипед был создан».выход.

Если вы говорите, что не хотите видеть «Велосипед создан».вывод при создании MountainBike, вы можете захотеть обернуть создание Bicycle или MountainBike другим классом, который знает, какой вывод отображать.Но по сути то, что вы видите в выводе, это то, что вы ожидаете увидеть как MountainBike - это также Bicycle.

public class BikeWarehouse {

    public Bicycle buildBicycle(int speed) {
        Bicycle bicycle = new Bicycle(speed);
        System.out.println("A Bicycle has been created.");
        return bicycle;
    }

    public MountainBike buildMountainBike(int seatHeight, int speed) {
        MountainBike mountainBike = new MountainBike(seatHeight, speed);
        System.out.println("A MountainBike has been created.");
        return mountainBike;
    }
}

Или вы можете поставить toString()метод в классах Bicycle и MountainBike, а затем при создании любого из них вы можете просто иметь:

System.out.println("A " + bike + " has been created");

Очевидно, toString() из Bicycle вернет "Bicycle" и toString() из MountainBike вернуло бы "MountainBike".

Я также не слишком часто использую аспекты, но я считаю, что возможно сделать что-то подобное вышеупомянутому, не засоряя вашу базу кода (если вы обнаружите, чтовыше "сорить"), но вы можете войти в систему создания ваших объектов, используя что-то вроде AspectJ.Я обычно не большой поклонник слишком многих решений на основе аспектов, но, возможно, стоит подумать.

1 голос
/ 29 ноября 2010

Ответы:

  1. Это не недостаток. Это особенность. Серьезно: -)

  2. Переместить 'System.out.println ("XXX был создан.") В защищенный метод и использовать его вместо статического вызова System.out.println.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...