Абстрактные классы предлагают способ определить шаблон поведения, где пользователь вставляет детали.
Один хороший пример - Java 6 SwingWorker . Он определяет платформу для выполнения чего-либо в фоновом режиме, требуя от пользователя определения doInBackground () для конкретной задачи.
Я расширил этот класс так, что он автоматически создал всплывающую панель прогресса. Я переопределил done (), чтобы контролировать удаление этого всплывающего окна, но затем предоставил новую точку переопределения, позволяющую пользователю дополнительно определять, что происходит после исчезновения индикатора выполнения.
public abstract class ProgressiveSwingWorker<T, V> extends SwingWorker<T, V> {
private JFrame progress;
public ProgressiveSwingWorker(final String title, final String label) {
SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("serial")
@Override
public void run() {
progress = new JFrame() {{
setLayout(new MigLayout("","[grow]"));
setTitle(title);
add(new JLabel(label));
JProgressBar bar = new JProgressBar();
bar.setIndeterminate(true);
add(bar);
pack();
setLocationRelativeTo(null);
setVisible(true);
}};
}
});
}
/**
* This method has been marked final to secure disposing of the progress dialog. Any behavior
* intended for this should be put in afterProgressBarDisposed.
*/
@Override
protected final void done() {
progress.dispose();
try {
afterProgressBarDisposed(get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
protected void afterProgressBarDisposed(T results) {
}
}
У пользователя все еще есть требование обеспечить реализацию doInBackground () . Однако они также могут иметь последующее поведение, например открывать другое окно, отображать JOptionPane с результатами или просто ничего не делать.
Чтобы использовать это:
new ProgressiveSwingWorker<DataResultType, Object>("Editing some data", "Editing " + data.getSource()) {
@Override
protected DataResultType doInBackground() throws Exception {
return retrieve(data.getSource());
}
@Override
protected void afterProgressBarDisposed(DataResultType results) {
new DataEditor(results);
}
}.execute();
Это показывает, как абстрактный класс может красиво представить шаблонную операцию, ортогональную концепции интерфейсов, определяющих контракт API.