Конструкторы в Java: Правила и особенности

Java

Как известно, объект является экземпляром определенного класса. Для его создания используется ключевое слово new, например:

Person student = new Person(“Mike”)

Этим кодом создается новый объект Person и указывается его имя – Mike. Строка «Mike» передается аргументом соответствующему конструктору Person:

Person(String name) {
    this.name = name;
}

Этот конструктор позволяет указать имя человека при создании объекта.

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

  • Конструкторы имеют то же имя, что и имя класса.
  • Конструкторы, как и методы, имеют список принимаемых параметров, но не имеют возвращаемый тип (даже void).

Ниже представлен набор из 7 основных правил работы с конструкторами, позволяющие полностью разобраться в их работе.

1. Конструкторы можно перегружать:

Это означает, что класс может иметь множество различных конструкторов, если их списки параметров различны. Например:

class Rectangle {
    int width;
    int height;

    Rectangle() {
        width = 1;
        height = 1;
    }

    Rectangle(int width) {
        this. width = width;
        this. height = width;
    }

    Rectangle(int width, int height) {
        this. width = width;
        this. height = height;
    }
}

Имея три различных конструктора Rectangle можно создавать новый объект тремя различными способами:

Rectangle rect1 = new Rectangle();
Rectangle rect2 = new Rectangle(10);
Rectangle rect3 = new Rectangle(10,20);

2. Конструктор по умолчанию:

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

Например, если мы напишем класс Rectangle следующим образом:

Class Rectangle {
    int widh, height;
    int area() { }
    int perimeter() { }
}

То компилятор автоматически вставляет конструктор по умолчанию:

ectangle() { }

3. Компилятор не будет генерировать конструктор по умолчанию, если в классе уже есть конструктор:

Рассмотрим следующий пример:

class Rectangle {
	int width;
	int height;

	Rectangle(int width) {
		this. width = width;
		this. height = width;
	}

	Rectangle(int width, int height) {
		this. width = width;
		this. height = height;
	}
}

При попытке создать новый объект:

Rectangle rect1 = new Rectangle();

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

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

В отличие от методов, конструкторы не наследуются. Пример:

class Rectangle {
    Rectangle(int width, int height) { }
}
class Square extends Rectangle {

}

Нельзя сделать что-то вроде этого: Square box = new Square(10, 10);

5. Конструкторы могут быть приватными!

Можно сделать конструктор приватным, чтобы не дать внешнему коду создать новый экземпляр класса. В чем же может быть преимущество приватного конструктора?

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

6. Конструктор по умолчанию имеет тот же модификатор доступа, что и класс:

При написании следующего класса: public class Person { }

Компилятор при вставке конструктора по умолчанию, укажет и необходимый модификатор доступа: public Preson();

7. Первой строкой любого конструктора должен вызываться либо перегруженный конструктор того же класса или конструктор его суперкласса:

Если это не так, то компилятор автоматически допишет вызов конструктора суперкласса без аргументов super(); Это может привести к ошибке, поскольку такого конструктора может не быть в суперклассе. Пример:

class Parent {
	Parent(int number) {
	}
}

class Child extends Parent {
	Child() {
	}
}

Приведет к ошибке, потому что компилятор вставляет вызов super () в конструкторе класса Child:

Child() {
    super();// дописал компилятор
}

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

Михаил Миронов

Живу в Нижнем Новгороде, работаю программистом с 2017 года, основная специализация Java, но также хорошо знаю PHP, Python, XML, HTML/CSS.

Добавить комментарий