#java #abstract-class #superclass
#java #наследование
Вопрос:
Рассмотрим следующий класс
class A{
public void init(){
//do this first;
}
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
@Override
public void init()
{
super.init();
//do new stuff.
//I do not want to call atEnd() method here...
}
}
У меня есть несколько B1, B2,… Bn дочерних классов, которые уже разработаны. Все они расширяют класс A. Если я хочу добавить новую функциональность во все из них, лучшее место для этого — определить это в методе внутри класса A. Но условием является то, что метод всегда должен вызываться автоматически непосредственно перед завершением метода init() дочернего класса.
Один из основных способов сделать это — снова добавить вызов метода atEnd() в конце метода init() дочерних классов. Но есть ли какой-либо другой способ сделать это разумно??
Ответ №1:
Один из способов сделать это — сделать init()
final и делегировать его работу второму, переопределяемому методу:
abstract class A {
public final void init() {
// insert prologue here
initImpl();
// insert epilogue here
}
protected abstract void initImpl();
}
class B extends A {
protected void initImpl() {
// ...
}
}
Всякий раз, когда кто-либо вызывает init()
, пролог и эпилог выполняются автоматически, и производным классам ничего не нужно делать.
Ответ №2:
Другой мыслью было бы включить аспект. Добавьте рекомендации «до» и «после» к точечному вырезу.
Комментарии:
1. Если речь идет о защите инвариантов класса, AOP был бы очень плохим решением.
2. Речь идет о «делать вещи»; инварианты не упоминаются. И я не уверен, что «очень плохой» подходит, основываясь на предоставленной информации.
Ответ №3:
Создайте init()
final
и предоставьте людям отдельный метод для переопределения этих init()
вызовов в середине:
class A{
public final void init(){
//do this first;
}
protected void initCore() { }
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
@Override
protected void initCore()
{
//do new stuff.
}
}
Ответ №4:
Другие ответы являются разумными обходными путями, но для решения точного вопроса: нет, нет способа сделать это автоматически. Вы должны явно вызвать super.method()
.