Java Language                
            Конструкторы
        
        
            
    Поиск…
Вступление
Хотя это и не требуется, конструкторы в Java - это методы, распознаваемые компилятором для создания конкретных значений для класса, которые могут быть существенными для роли объекта. В этом разделе показано правильное использование конструкторов классов Java.
замечания
Спецификация языка Java подробно обсуждает точный характер семантики конструктора. Их можно найти в JLS §8.8
Конструктор по умолчанию
 «Default» для конструкторов состоит в том, что у них нет аргументов. Если вы не укажете какой-либо конструктор, компилятор создаст для вас конструктор по умолчанию. 
 Это означает, что следующие два фрагмента семантически эквивалентны: 
public class TestClass {
    private String test;
}
public class TestClass {
    private String test;
    public TestClass() {
    }
}
Видимость конструктора по умолчанию такая же, как видимость класса. Таким образом, для класса, определенного для пакета, в частном порядке есть конструктор по умолчанию для пакета-частного
Однако, если у вас есть конструктор, отличный от стандартного, компилятор не создаст для вас конструктор по умолчанию. Таким образом, они не эквивалентны:
public class TestClass {
    private String test;
    public TestClass(String arg) {
    }
}
public class TestClass {
    private String test;
    public TestClass() {
    }
    public TestClass(String arg) {
    }
}
Помните, что сгенерированный конструктор не выполняет нестандартную инициализацию. Это означает, что все поля вашего класса будут иметь значение по умолчанию, если у них нет инициализатора.
public class TestClass {
    private String testData;
    public TestClass() {
        testData = "Test"
    }
}
Конструкторы называются так:
TestClass testClass = new TestClass();
Конструктор с аргументами
Конструкторы могут быть созданы с любыми аргументами.
public class TestClass {
    private String testData;
    public TestClass(String testData) {
        this.testData = testData;
    }
}
Вызывается следующим образом:
TestClass testClass = new TestClass("Test Data");
 Класс может иметь несколько конструкторов с разными сигнатурами. Чтобы вызвать вызовы конструктора (вызовите другой конструктор того же класса при создании экземпляра), используйте this() . 
public class TestClass {
    private String testData;
    public TestClass(String testData) {
        this.testData = testData;
    }
    public TestClass() {
        this("Test"); // testData defaults to "Test"
    }
}
Вызывается следующим образом:
TestClass testClass1 = new TestClass("Test Data");
TestClass testClass2 = new TestClass();
Вызов родительского конструктора
 Скажем, у вас есть класс родителя и класс ребенка. Для создания экземпляра Child всегда требуется, чтобы какой-либо родительский конструктор запускался с самого начала конструктора Child. Мы можем выбрать конструктор родителя, который мы хотим, явным образом вызываем super(...) с соответствующими аргументами как наш первый оператор конструктора Child. Это экономит время, повторно используя конструктор родительских классов вместо того, чтобы переписать один и тот же код в конструкторе дочерних классов. 
 Без super(...) метода: 
 (неявно, версия no-args super() называется невидимо) 
class Parent {
    private String name;
    private int age;
    
    public Parent() {} // necessary because we call super() without arguments
    
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}
// This does not even compile, because name and age are private,
// making them invisible even to the child class.
class Child extends Parent {
    public Child() {
        // compiler implicitly calls super() here
        name = "John";
        age = 42;
    }
}
 С методом super() : 
class Parent {
    private String name;
    private int age;
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}
class Child extends Parent {
    public Child() {
        super("John", 42);   // explicit super-call
    }
}
Примечание. Вызовы к другому конструктору (цепочке) или суперконструктору ДОЛЖНЫ быть первым утверждением внутри конструктора.
 Если вы явно вызываете конструктор super(...) , должен существовать соответствующий родительский конструктор (это просто, не так ли?). 
 Если вы не вызываете конструктор super(...) явно, ваш родительский класс должен иметь конструктор no-args - и это может быть либо явно написано, либо создано по умолчанию компилятором, если родительский класс не предоставляет любой конструктор. 
class Parent{
    public Parent(String tName, int tAge) {}
}
class Child extends Parent{
    public Child(){}
}
 Класс Parent не имеет конструктора по умолчанию, поэтому компилятор не может добавить super в конструктор Child. Этот код не будет компилироваться. Вы должны изменить конструкторы, чтобы они соответствовали обеим сторонам, или написать собственный super , например: 
class Child extends Parent{
    public Child(){
          super("",0);
    }
}