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);
}
}