Может ли абстрактный класс иметь конструктор?
Проблема: Может ли абстрактный класс иметь конструктор?
Если да, то как его можно использовать и для каких целей?
5 ответ(ов)
Да, абстрактный класс может иметь конструктор. Рассмотрим следующий пример:
abstract class Product {
int multiplyBy;
public Product(int multiplyBy) {
this.multiplyBy = multiplyBy;
}
public int multiply(int val) {
return multiplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
В данном случае суперкласс Product
является абстрактным и имеет конструктор. Конкретный класс TimesTwo
имеет конструктор, который просто фиксирует значение 2. Конкретный класс TimesWhat
имеет конструктор, который позволяет вызвать этот класс с указанным значением.
Конструкторы в абстрактных классах часто используются для обеспечения ограничений классов или инвариантов, таких как минимальные поля, необходимые для инициализации класса.
Обратите внимание: поскольку в родительском абстрактном классе нет конструктора по умолчанию (или конструктора без аргументов), конструктор, используемый в подклассе, должен явно вызывать конструктор родительского класса.
Вы можете определить конструктор в абстрактном классе в следующих ситуациях:
- Если вам нужно выполнить инициализацию (полей абстрактного класса) до фактической инстанциации подкласса.
- Если вы определили финальные поля в абстрактном классе, но не инициализировали их при объявлении; в этом случае вам ОБЯЗАТЕЛЬНО нужен конструктор для их инициализации.
Обратите внимание на следующее:
- Вы можете определить несколько конструкторов (с разными аргументами).
- Рекомендуется определять все ваши конструкторы как protected (делать их public не имеет смысла).
- Конструкторы подкласса могут вызывать конструктор абстрактного класса; это может быть даже обязанностью вызвать его (если в абстрактном классе отсутствует конструктор без аргументов).
И не забывайте, что если вы не определите конструктор, компилятор автоматически сгенерирует его за вас (он будет public, без аргументов и ничего не будет делать).
Да, абстрактный класс может иметь конструктор, и он определяется и ведет себя так же, как конструктор любого другого класса. Однако абстрактные классы не могут быть непосредственно инстанциированы, они только расширяются, поэтому использование конструктора абстрактного класса всегда происходит из конструктора подкласса.
Да! Абстрактные классы могут иметь конструкторы!
Да, когда мы определяем класс как абстрактный, его нельзя инстанцировать, но это не означает, что абстрактный класс не может содержать конструктор. Каждый абстрактный класс должен иметь конкретный подкласс, который реализует абстрактные методы этого абстрактного класса.
Когда мы создаем объект любого подкласса, все конструкторы в соответствующем дереве наследования вызываются сверху вниз. То же самое справедливо и для абстрактных классов. Хотя мы не можем создать объект абстрактного класса, при создании объекта конкретного класса, который является подклассом абстрактного класса, конструктор абстрактного класса автоматически вызывается. Таким образом, у нас могут быть конструкторы в абстрактных классах.
Примечание: Некачественный класс не может иметь абстрактные методы, но абстрактный класс может иметь неабстрактные методы. Причина аналогична той, что касается конструкторов, только вместо автоматического вызова мы можем использовать вызов super(). Также не существует такого понятия, как абстрактный конструктор, поскольку это абсолютно бессмысленно.
Хотя есть много хороших ответов, я хотел бы добавить свои 2 копейки.
Конструктор НЕ СОЗДАЕТ ОБЪЕКТ. Он используется для инициализации объекта.
Да, у абстрактного класса всегда есть конструктор. Если вы не определите собственный конструктор, компилятор предоставит абстрактному классу конструктор по умолчанию. Это верно для всех классов — вложенных, абстрактных, анонимных и т.д.
Абстрактный класс (в отличие от интерфейса) может иметь нефинальные нестатические поля, которые требуют инициализации. Вы можете написать свой собственный конструктор в абстрактном классе для этой цели. Однако в этом случае не будет конструктора по умолчанию.
public abstract class Abs {
int i;
int j;
public Abs(int i, int j) {
this.i = i;
this.j = j;
System.out.println(i + " " + j);
}
}
Будьте осторожны при расширении вышеприведенного абстрактного класса: вам нужно явным образом вызывать super
из каждого конструктора. Первая строка любого конструктора — это вызов super()
. Если вы не вызовете super()
явно, Java сделает это за вас.
Ниже приведенный код не скомпилируется:
public class Imp extends Abs {
public Imp(int i, int j, int k, int l) {
System.out.println("2 arg");
}
}
Вам нужно использовать его, как в следующем примере:
public class Imp extends Abs {
public Imp(int i, int j, int k, int l) {
super(i, j);
System.out.println("2 arg");
}
}
Как вызвать один конструктор из другого в Java?
Как инициализировать значения HashSet при создании?
Почему статические методы не могут быть абстрактными в Java?
Почему this() и super() должны быть первыми выражениями в конструкторе?
Как мне следовало объяснить разницу между интерфейсом и абстрактным классом? [закрыто]