Поиск…


Вступление

Хотя это и не требуется, конструкторы в 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);
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow