метод вызова Java в конструкторе и абстрактном классе?

#java #constructor

#java #конструктор

Вопрос:

 public class NewSeqTest {
  public static void main(String[] args) {
    new S();
    new Derived(100);
  }
}


class P {
  String s = "parent";
  public P() {
    test();
  }
  public void test() { //test 1
    System.out.println(s   "  parent");
  }
}

class S extends P {
  String s = "son";
  public S() {
    test();
  }
  @Override
  public void test() { //test 2
    System.out.println(s   "  son");
  }
}

abstract class Base {
  public Base() {
    print();
  }
  abstract public void print();
}

class Derived extends Base {
  private int x = 3;
  public Derived(int x) {
    this.x = x;
  }
  @Override
  public void print() {
    System.out.println(x);
  }
}
  

// вывод

      null  son

     son  son

     0
  

мой вопрос
1. почему конструктор P печатает «нулевой сын»; Я думаю, что это «нулевой родитель»?

2 почему абстрактный класс Base может выполнять абстрактный метод print() в конструкторе?

извините за формат кода, я не знаю, как его правильно использовать.

Ответ №1:

  1. Вы переопределили метод test в своем подклассе S и создаете объект типа S . Итак, в конструкторе суперкласса при test() вызове он вызывает переопределенную версию test() из подкласса S . В этом смысл переопределения.

  2. То же, что и 1. Метод print не является абстрактным в классе Derived , и вы создаете экземпляр Derived , а не of Base . (Незаконно говорить new Base() по причине, которую вы упомянули: вы не можете вызвать абстрактный метод)

Ответ №2:

  1. Выполнение new S(); вызывает P запуск конструктора test() . Он выполняет переопределенный test() , в S котором печатается s . Он использует s in S , который не был инициализирован, потому что конструктор S выполняется после конструктора P .
    2. Тот же ответ, что и для 1. Переопределенный print() выполняется, но x еще не инициализирован.

кстати: попробуйте использовать отладчик и запустить программу шаг за шагом, чтобы следовать пути выполнения.