Какой метод вызывается при выполнении цепочки конструктора с переопределенным методом - PullRequest
0 голосов
/ 28 января 2012

Какой метод вызывается при выполнении цепочки конструктора с помощью переопределенного метода?Учитывая следующие два класса, мне нужно знать, какой метод setGear будет вызываться при создании объекта MountainBike.Мой настоящий проект не имеет ничего общего с велосипедами, я пытаюсь переопределить класс, чтобы изменить поведение одного метода, который вызывается в конструкторе суперкласса, и я не уверен, как он должен работать ...

public class Bicycle {
    public int cadence;
    public int gear;
    public int speed;

    public Bicycle(int startCadence,
                   int startSpeed,
                   int startGear) {
        setGear(startGear);
        setCadence(startCadence);
        setSpeed(startSpeed);
    }

    public void setCadence(int newValue) {
        cadence = newValue;
    }

    public void setGear(int newValue) {
        gear = newValue;
    }

    public void applyBrake(int decrement) {
        speed -= decrement;
    }

    public void speedUp(int increment) {
        speed += increment;
    }        
}

public class MountainBike extends Bicycle {
    public int seatHeight;

    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   

    public void setHeight(int newValue) {
        seatHeight = newValue;
    }

    public void setGear(int newValue) {
    if(newValue<4)
            gear = newValue;
        else{
            gear = 4;
        }

    }    
}

Ответы [ 6 ]

1 голос
/ 28 января 2012

Как отметили другие, вызывается подкласс 'setGear.

Однако я хотел бы упомянуть, что вызов переопределенных методов в конструкторе опасен и осуждается , особенно если эти методы полагаются на поля подкласса . Например, если MountainBike имел поле, maxGear и setGear ссылались на него (вместо магической константы 4). Проблема в том, что ваш конструктор MountainBike выглядит примерно так:

public MountainBike(args...) {
  super(args);  // must come first!!!
  maxGear = 4;
}

Когда конструктор Bicycle вызывает setGear (), он будет вызывать MountainBike setGear, , но maxGear еще не установлен - будет 0.

1 голос
/ 28 января 2012

Здесь есть несколько хороших ответов, но я хотел бы отметить, что вы должны рассмотреть вместо этого использование композиции.Я видел много проектов, в которых наследование использовалось для функций, которые могли бы быть намного лучше с композицией.На более поздних этапах проекта это может привести к серьезным проблемам и запахам кода.

См. «Композиция избранного по наследованию»: Действующая Java: элемент 16

1 голос
/ 28 января 2012

Если вы вызовете его, метод подкласса будет выполнен. Однако, это в настоящее время не вызывается.

0 голосов
/ 28 января 2012

В целом, вы не должны позволять ссылке на объект избегать своего конструктора, будь то, передавая "this" в качестве параметра методу другого класса или вызывая методы, которые можно переопределить.

Вы не должны вызывать переопределенные методы из конструктора суперкласса, даже если можете. Причина в том, что конструктор суперкласса запускается раньше, чем у подкласса, и состояние объекта может быть несовместимым. Например, окончательные поля в подклассе еще не установлены.

0 голосов
/ 28 января 2012

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

class A{methodA...}
class B extends A{methodA...}
A a=new B;
a.methodA(); <<<< this should call B's methodA
0 голосов
/ 28 января 2012

Если вы создаете экземпляр переопределяющего класса, то его переопределенные методы будут выполняться.

Bicycle bike;

bike = new Bicycle(1,2,3);
bike.setGear(8);//Bicycle's setGear is run

bike = new MountainBike(1,2,3,4);
bike.setGear(8);//MountainBike's setGear is run

- Редактировать : отразить отредактированный вопрос OP (setGear теперьвызывается из конструктора Bicycle) -

Bicycle b=new MountainBike(1,2,3,4);

Учитывая, что вы создаете экземпляр MountainBike, MountainBike 'setGear выполняется.

...