Лучше ли поставить стандартную реализацию метода в суперкласс и переопределить его, если подклассы хотят отклониться от этого, или вы должны просто оставить абстрактный метод суперкласса и повторить обычную реализацию во многих подклассах?
Например, в проекте, в котором я участвую, есть класс, который используется для указания условий, в которых он должен останавливаться. Абстрактный класс выглядит следующим образом:
public abstract class HaltingCondition{
public abstract boolean isFinished(State s);
}
Тривиальная реализация может быть:
public class AlwaysHaltingCondition extends HaltingCondition{
public boolean isFinished(State s){
return true;
}
}
Причина, по которой мы делаем это с объектами, состоит в том, что мы можем тогда произвольно составить эти объекты вместе. Например:
public class ConjunctionHaltingCondition extends HaltingCondition{
private Set<HaltingCondition> conditions;
public void isFinished(State s){
boolean finished = true;
Iterator<HaltingCondition> it = conditions.iterator();
while(it.hasNext()){
finished = finished && it.next().isFinished(s);
}
return finished;
}
}
Однако у нас есть некоторые условия остановки, которые необходимо уведомлять о том, что произошли события. Например:
public class HaltAfterAnyEventHaltingCondition extends HaltingCondition{
private boolean eventHasOccurred = false;
public void eventHasOccurred(Event e){
eventHasOccurred = true;
}
public boolean isFinished(State s){
return eventHasOccurred;
}
}
Как лучше всего представить eventHasOccurred(Event e)
в абстрактном суперклассе? Большинство подклассов могут иметь не-op реализацию этого метода (например, AlwaysHaltingCondition
), в то время как для некоторых требуется значительная реализация для правильной работы (например, HaltAfterAnyEventHaltingCondition
), а другим ничего не нужно делать с сообщением, но нужно передать его на своих подчиненных, чтобы они работали правильно (например, ConjunctionHaltingCondition
).
У нас может быть реализация по умолчанию, которая уменьшит дублирование кода, но приведет к компиляции некоторых подклассов, но не будет корректно работать, если она не была переопределена, или мы могли бы объявить ее абстрактным, что потребовало бы автора каждый подкласс, чтобы подумать о реализации, которую они предоставляют, хотя девять раз из десяти он был бы не-op-реализацией. Каковы другие плюсы и минусы этих стратегий? Является ли это намного лучше, чем другой?