Можно выбрать, использовать конструктор суперкласса или нет?
Невозможно условно контролировать, использовать или нет конструктор суперкласса, так как один из конструкторов суперкласса должен быть вызван перед созданием собственного объекта.
Исходя из вышесказанного, в Java есть требование, чтобы первая строка конструктора вызывала конструктор суперкласса - фактически, даже если явного вызова конструктора суперкласса нет, будет неявный вызов super()
:
public class X {
public X() {
// ...
}
public X(int i) {
// ...
}
}
public class Y extends X {
public Y() {
// Even if not written, there is actually a call to super() here.
// ...
}
}
Следует подчеркнуть, что невозможно вызвать конструктор суперкласса после выполнения чего-то еще:
public class Y extends X {
public Y() {
doSomething(); // Not allowed! A compiler error will occur.
super(); // This *must* be the first line in this constructor.
}
}
Альтернатива
Тем не менее, для достижения желаемого здесь можно использовать шаблон фабричного метода , который может выбирать тип реализации в зависимости от некоторого условия:
public A getInstance() {
if (condition) {
return new B();
} else {
return new C();
}
}
В приведенном выше коде, в зависимости от condition
, метод может возвращать либо экземпляр B
, либо C
(при условии, что оба являются подклассом класса A
).
Пример
Ниже приведен конкретный пример использования interface
вместо class
.
Пусть будут следующие интерфейсы и классы:
interface ActionPerformable {
public void action();
}
class ActionPerformerA implements ActionPerformable {
public void action() {
// do something...
}
}
class ActionPerformerB implements ActionPerformable {
public void action() {
// do something else...
}
}
Тогда будет класс, который будет возвращать один из вышеперечисленных классов в зависимости от условия, переданного через метод:
class ActionPeformerFactory {
// Returns a class which implements the ActionPerformable interface.
public ActionPeformable getInstance(boolean condition) {
if (condition) {
return new ActionPerformerA();
} else {
return new ActionPerformerB();
}
}
}
Затем класс, который использует вышеуказанный фабричный метод, который возвращает соответствующую реализацию в зависимости от условия:
class Main {
public static void main(String[] args) {
// Factory implementation will return ActionPerformerA
ActionPerformable ap = ActionPerformerFactory.getInstance(true);
// Invokes the action() method of ActionPerformable obtained from Factory.
ap.action();
}
}