1

Прочитал в общих сведениях о конструкторах что, Конструкторы не наследуются, источник: Клик

Сделал такой пример и получилось, что конструкторы наследуются:

public class Car {

    public Car() {
        System.out.println("Машина");
    }
}

public class Bmw extends Car {

}


public class Qwerty {
    public static void main(String[] args) {
        Car car = new Car();
        Bmw bmw = new Bmw();
    }
}

Вывод в консоли:
Машина
Машина

  • За Вас поработал компилятор. –  Apr 18 '19 at 18:02
  • @Igor а как научиться понимать вот такие вещи? То есть прочитал что наследование конструкторов не работает, а по факту работает на практике, тогда что говорить на собеседовании чтобы сказать правильно? –  Apr 18 '19 at 18:03
  • @MikeMclaren для понимания таких вещей надо внимательно прочитать учебник, только и всего. – Sergey Gornostaev Apr 18 '19 at 18:21
  • @SergeyGornostaev с английским проблема, я учу каждый день. А книжки и статьи читаю по максимому –  Apr 18 '19 at 18:23
  • 1
    @MikeMclaren есть множество прекрасных учебников на русском. – Sergey Gornostaev Apr 18 '19 at 18:23
  • @SergeyGornostaev подскажите пожалуйста, я читаю "Изучаем Java" Кети Сиерра, какие еще есть? Я всё прочту! –  Apr 18 '19 at 18:46
  • @MikeMclaren хороший выбор для старта. После неё можно начать читать один учебник за другим из раздела "Средний уровень" этого списка. – Sergey Gornostaev Apr 18 '19 at 18:57
  • @SergeyGornostaev Так вы же сами говорили на русском кроме Сиерры, в остальных книгах перевод не очень?) –  Apr 19 '19 at 04:28
  • @MikeMclaren не очень перевод у Шилдта, про остальные я этого не говорил. Впрочем, огрехи могут встречаться и в других учебниках, но с ростом объёма знаний они будут меньше мешать. – Sergey Gornostaev Apr 19 '19 at 04:48
  • @SergeyGornostaev спасибо большое! –  Apr 19 '19 at 11:42

2 Answers2

6

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

class Car {
    public Car(int speed) {
        System.out.println("Машина");
    }
}

class Bmw extends Car { }

public class Example {
    public static void main(String[] args) {
        Bmw bmw = new Bmw(200);
    }
}

При компиляции получите ошибку

Example.java:7: error: constructor Car in class Car cannot be applied to given types;
class Bmw extends Car { }
^
  required: int
  found: no arguments
  reason: actual and formal argument lists differ in length
App.java:13: error: constructor Bmw in class Bmw cannot be applied to given types;
        Bmw bmw = new Bmw(200);
                  ^
  required: no arguments
  found: int
  reason: actual and formal argument lists differ in length
2 errors

Из ошибки понятно, что в Bmw нет конструктора принимающего целочисленный аргумент, а значит он не унаследовался от Car.

Когда вы явно не объявляете конструктор, компилятор создаёт конструктор без аргументов, содержащий ровно одну строку кода - вызов конструктора без аргументов родительского класса:

class Bmw extends Car {                                               
  Bmw();                                                              
    Code:                                                             
       0: aload_0                                                     
       1: invokespecial #1    // Method Car."<init>":()V
       4: return                                                      
}

Чтобы создать объект, виртуальная машина должна вызвать конструктор его класса и всех родительских, вплоть до Object. Поэтому вы видите вывод строки "Машина".

  • Какой раз поражаюсь вашими очень расширенными ответами, огромное спасибо! –  Apr 18 '19 at 18:22
2

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

Получается, что в классе Bmw неявно определён такой конструктор:

public Bmw() {
    super();
}

Спецификация.

Этот случай не является наследованием конструкторов, потому что вы в любом случае создаёте объект Bmw с помощью конструктора класса Bmw, пусть и объявленного неявно. Если вы добавите в класс Bmw любой конструктор явно, то конструктор по умолчанию создаваться уже не будет.

  • а как научиться понимать вот такие вещи? То есть прочитал что наследование конструкторов не работает, а по факту работает на практике, тогда что говорить на собеседовании чтобы сказать правильно? –  Apr 18 '19 at 18:07
  • @MikeMclaren, при чём здесь наследование конструкторов? При создании объекта Bmw вызывается именно конструктор класса Bmw. Так получилось, что он дефолтный, поэтому работает так же, как и конструктор класса Car. Вам ничего не мешает явно написать конструктор из моего ответа. От этого механизм создания объектов не поменяется. – Кирилл Малышев Apr 18 '19 at 18:10
  • @MikeMclaren, если вы добавите в класс Bmw ещё один любой конструктор, то конструктор по умолчанию создаваться уже не будет и вам придётся описывать явно конструктор без аргументов. – Кирилл Малышев Apr 18 '19 at 18:13
  • Спасибо!!!!!!!! –  Apr 18 '19 at 18:22