Polimorfizm w czasie wykonywania w Javie bez „abstrakcji”?

Przejrzałem oficjalny samouczek Oracle, w którym wprowadza on ideę polimorfizmu na przykładzie hierarchii klas 3 klas; Rower jest superklasą, a MountainBike i RoadBike to dwie podklasy.

Pokazuje, jak 2 podklasy zastępują metodę „printDescription” zadeklarowaną w Rowerach, deklarując jej różne wersje.

I wreszcie pod koniec samouczek wspomina, że ​​Java Virtual Machine (JVM) wywołuje odpowiednią metodę dla obiektu, do którego odnosi się każda zmienna.

Jednak tutorial dotyczący polimorfizmu nigdzie nie wspomina o koncepcji „abstrakcyjnych” klas i metod. W jaki sposób osiąga się polimorfizm w czasie wykonywania, chyba że printDescription () na rowerze jest deklarowany jako „abstrakcyjny”? Mam na myśli, biorąc pod uwagę ten przykład, na podstawie podpowiedzi, które kompilator decyduje się nie wiązać wywołaniem metody z typem odniesienia w czasie kompilacji, i sądzą, że powinien on pozostawić JVMowi do czynienia w czasie wykonywania?

Poniżej zastosowano przykład:

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

    public Bicycle(int startCadence, int startSpeed, int startGear) {
      gear = startGear;
      cadence = startCadence;
      speed = 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 void printDescription(){
        System.out.println("\nBike is " + "in gear " + this.gear
         + " with a cadence of " + this.cadence +
         " and travelling at a speed of " + this.speed + ". ");
    }

}

public class MountainBike extends Bicycle {
  private String suspension;

  public MountainBike(
           int startCadence,
           int startSpeed,
           int startGear,
           String suspensionType){
    super(startCadence,
          startSpeed,
          startGear);
    this.setSuspension(suspensionType);
  }

  public String getSuspension(){
    return this.suspension;
  }

  public void setSuspension(String suspensionType) {
    this.suspension = suspensionType;
  }

  public void printDescription() {
    super.printDescription();
    System.out.println("The " + "MountainBike has a" +
        getSuspension() + " suspension.");
  }

}

public class RoadBike extends Bicycle{

  private int tireWidth;

  public RoadBike(int startCadence,
                int startSpeed,
                int startGear,
                int newTireWidth){
    super(startCadence,
          startSpeed,
          startGear);
    this.setTireWidth(newTireWidth);
  }

  public int getTireWidth(){
    return this.tireWidth;
  }

  public void setTireWidth(int newTireWidth){
    this.tireWidth = newTireWidth;
  }

  public void printDescription(){
    super.printDescription();
    System.out.println("The RoadBike"
        " has " + getTireWidth() +
        " MM tires.");
  }
}


public class TestBikes {
    public static void main(String[] args){
        Bicycle bike01, bike02, bike03;

      bike01 = new Bicycle(20, 10, 1);
      bike02 = new MountainBike(20, 10, 5, "Dual");
      bike03 = new RoadBike(40, 20, 8, 23);

      bike01.printDescription();
      bike02.printDescription();
      bike03.printDescription();
      }
}

questionAnswers(6)

yourAnswerToTheQuestion