Конструкторы и наследование по умолчанию в Java

У меня вопрос о конструкторах по умолчанию и наследовании в Java.

Как правило, если вы пишете класс и не включаете какой-либо конструктор, Java автоматически предоставляет вам конструктор по умолчанию (один без параметров), который инициализирует все переменные экземпляра класса (если они есть) с некоторыми значениями по умолчанию ( 0, null или false). Однако, если вы пишете конструктор с некоторыми параметрами и не создаете конструктор по умолчанию, то Java не предоставляет конструктор по умолчанию. Мой вопрос: что происходит с классами, которые наследуются от других классов - если я пишу конструктор с некоторыми параметрами в них, но не включаю конструктор по умолчанию, наследуют ли они конструктор по умолчанию суперкласса?

Ответ 2

Конструкторы не наследуются.

Кроме того, инициализация полей выполняется виртуальной машиной, а не конструктором по умолчанию. Конструктор по умолчанию просто вызывает конструктор по умолчанию суперкласса, а конструктор по умолчанию Object пуст. Хорошей точкой этого дизайна является отсутствие возможности доступа к неинициализированным полям.

Ответ 3

Если вы не используете super (...), конструктор вызывает пустой конструктор своего родителя. Примечание. Это делается на всех ваших классах, даже тех, которые расширяют Object.

Это не наследует, подклассы не получают тех же конструкторов с теми же аргументами. Однако вы можете добавить конструкторы, которые вызывают один из конструкторов суперкласса.

Ответ 4

Основным правилом является вызов (или вызов) в конструктор, который должен быть первым оператором, который должен выполнить JVM,

Итак, когда у вас есть суперкласс с только параметризованным конструктором и конструктором по умолчанию, а базовый класс не имеет явного вызова параметризованного конструктора суперкласса, JVM предоставляет super(); вызов, который вызывает ошибку, поскольку для суперкласса не существует конструктора по умолчанию, поэтому либо мы предоставляем конструктор по умолчанию в суперклассе, либо явным образом вызываем конструктор с параметризацией суперкласса в конструкторе базового класса. когда мы даем явный вызов, тогда JVM не утруждает себя строкой super(); поскольку вызов конструктора должен быть первым выражением метода, которого не может произойти (из-за нашего явного вызова).

Ответ 5

В разделе 8.8.9 Спецификации языка Java подробно объясняется, что происходит:

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

  • Конструктор по умолчанию имеет такую ​​же доступность, как класс (§6.6).
  • Конструктор по умолчанию не имеет формальных параметров, кроме как в неличном внутренний класс-член, где конструктор по умолчанию неявно объявляет один формальный Параметр, представляющий непосредственно входящий экземпляр класса (§8.8.1, §15.9.2, §15.9.3).
  • Конструктор по умолчанию не имеет предложений бросков.
  • Если объявляемый класс является искомым объектом класса, то значение по умолчанию конструктор имеет пустое тело. В противном случае конструктор по умолчанию просто вызывает конструктор суперкласса без аргументов.

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

Ответ 6

Если вы предоставите конструктор, то Java не будет генерировать пустой конструктор по умолчанию. Таким образом, ваш производный класс сможет вызывать только ваш конструктор.

Конструктор по умолчанию не инициализирует ваши личные переменные значениям по умолчанию. Доказательство того, что можно написать класс, который не имеет конструктора по умолчанию, и имеет свои частные члены, инициализированные значениями по умолчанию. Вот пример:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}

Ответ 7

Правило Thumb - это то, что Sub Class должен вызывать любой конструктор из базового класса. поэтому, если у вас нет значения по умолчанию, вызовите существующий из подкласса. другие мудрые реализуют пустой const в базовом классе, чтобы избежать проблемы компиляции

Ответ 8

Ответ на ваш вопрос очень прост. Implicitly (Invisible), первый оператор в любом конструкторе - 'super();' т.е. вызов суперкласса no parameter constructor, пока вы явно не измените его на нечто вроде "this();", "this (int)", "this (String)", "super (int)", "super" (String )' и т.д. 'это();' является конструктором текущего класса.

Ответ 9

Когда мы не создаем конструктор, Java автоматически создает конструктор по умолчанию. Но когда мы создаем один или несколько настраиваемых конструкторов с аргументами, Java не создает конструкторы по умолчанию. Если мы создаем один или несколько конструкторов и хотим создать объект без каких-либо аргументов конструктора, мы должны объявить пустой конструктор.

Ответ 10

Будет ошибка времени компиляции... потому что компилятор ищет по умолчанию Constructor he Superclass, и если его нет... его ошибка... и программа не будет компилироваться...

Ответ 11

Любой конструктор в подклассе будет вызывать конструктор без аргументов (или конструктор по умолчанию) родительского класса. если вы определите параметризованный конструктор в родительском классе, то вам придется явно вызывать конструктор родительского класса с помощью ключевого слова super, иначе это вызовет ошибку компиляции.

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Приведенный выше код выдаст ошибку компиляции:

prog.java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
    { 
    ^
  required: int,int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

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

Теперь, чтобы решить это, либо вызовите параметризованный конструктор, например так:

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        super(4, 5); // calling the parameterized constructor of parent class
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Выход

base
derived

или же

определить конструктор без аргументов в родительском классе следующим образом:

class Alpha 
{ 
    Alpha(){

    }
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

выход

derived