Класс A происходит от абстрактного класса B и реализует абстрактный метод foo. Теперь в методе foo я хочу сделать что-то, что зависит от переменной-члена класса A, mType. Однако это приводит к ошибке, поскольку foo вызывается в конструкторе из абстрактного класса B, поэтому mType еще не инициализирован.Инициальная переменная-член перед вызовом конструктора базового класса
Невозможно инициализировать mType перед супер(), поэтому я не знаю, как это сделать. Конечно, я могу сделать mType членом B, но я думаю, что это не очень хороший способ, потому что mType не имеет никакого отношения к этому классу, в этом примере это, возможно, неясно, но, конечно, я переписал практическую ситуацию на короткий простой, чтобы объяснить проблему.
Что такое хороший способ решить эту проблему?
public abstract class B {
public B() {
foo(); // A::mType IS NOT INITIALISED!!
}
protected abstract void foo();
}
private class A extends B {
public enum Type { TYPE1, TYPE2 };
public A(Type aType) {
super();
mType = aType;
}
@Override
protected void foo() {
if (mType == Type.TYPE1) {
// ..
} else {
// ...
}
}
}
[Никогда не вызывайте переопределяемые методы из конструктора] (http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors). – Seelenvirtuose
Вы можете просто сделать любой код установки, который вы делаете в 'foo()' в конструкторе? Зачем переопределять его, если вы просто вызываете его немедленно? –
Плохая практика вызова переопределяемых методов в конструкторе, но если вы * must *, вы можете изменить подпись 'foo', чтобы взять' foo (Type) 'и делать все, что вы там хотите, то есть назначить своего участника и выполнить другую проверку и т.п. – webuster