Почему интерфейсы предпочтительнее абстрактных классов? - PullRequest
35 голосов
/ 12 марта 2009

Я недавно посетил интервью, и они задали мне вопрос «Почему интерфейсы предпочтительнее абстрактных классов?»

Я попытался дать несколько ответов, таких как:

  • Мы можем получить только одну Расширяемую функциональность
  • они на 100% абстрактные
  • Реализация не жестко закодирована

Они попросили меня взять любой из API JDBC, который вы используете. «Почему они интерфейсы?».

Могу ли я получить лучший ответ на этот вопрос?

Ответы [ 23 ]

0 голосов
/ 21 октября 2009

Абстрактные классы предлагают способ определить шаблон поведения, где пользователь вставляет детали.

Один хороший пример - 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.

0 голосов
/ 14 апреля 2009

Они попросили меня взять любой из API JDBC что вы используете. «Почему они Интерфейсы?».

Мой ответ на этот конкретный вопрос:

SUN не знает, как их реализовать или что поместить в реализацию. Поставщики услуг / поставщики БД должны реализовать свою логику в реализации.

Проект JDBC связан с шаблоном Bridge, который гласит: «Отсоедините абстракцию от его реализации, чтобы они могли варьироваться независимо».

Это означает, что иерархия интерфейсов API JDBC api может развиваться независимо от иерархии реализации, которую предоставляет или использует поставщик jdbc.

0 голосов
/ 13 марта 2009

Ну, я бы предложил перефразировать сам вопрос. Интерфейсы - это в основном контракты, которые приобретает класс, реализация этого контракта сама по себе будет отличаться. Абстрактный класс обычно будет содержать некоторую логику по умолчанию, а его дочерние классы добавят еще немного логики. Я бы сказал, что ответ на вопросы зависит от алмазной проблемы. Java предотвращает множественное наследование, чтобы избежать его. (http://en.wikipedia.org/wiki/Diamond_problem).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...