Java интерфейс и проблема абстрактного класса - PullRequest
7 голосов
/ 15 мая 2010

Я читаю книгу - Hadoop: полное руководство

В главе 2 (стр. 25) упоминается «Новый API предпочитает абстрактный класс интерфейсам, поскольку их легче развивать. Например, вы можете добавить метод (с реализацией по умолчанию) в абстрактный класс без ломая старые реализации класса ". Что это значит (особенно что означает «ломать старые реализации класса»)? Спасибо, если кто-нибудь может показать мне пример, почему с этой точки зрения абстрактный класс лучше интерфейса?

спасибо заранее, George

Ответы [ 3 ]

10 голосов
/ 15 мая 2010

В случае интерфейса все методы, которые определены в интерфейсе , должны быть реализованы классом, который его реализует.

Учитывая интерфейс A

interface A {
    public void foo();
}

и класс B:

class B implements A {
}

он должен предоставить реализацию метода, определенного в интерфейсе:

class B implements A {
    @Override
    public void foo() {
        System.out.println("foo");
    }
}

В противном случае это ошибка времени компиляции. Теперь возьмите абстрактный класс с реализацией метода по умолчанию :

abstract class C {
    public void bar() {
        System.out.println("bar");
    }
}

где класс, наследуемый от этого абстрактного класса, может выглядеть так:

class D extends C { }

без ошибок. Но он также может переопределить реализацию метода по умолчанию, если он склонен сделать это.

Что там говорил автор: если ваш API еще не стабилен и вам нужно адаптировать интерфейсы (да, абстрактные классы также являются интерфейсами (на языке ООП)), тогда абстрактный класс позволяет вам добавлять вещи без ломая классы, которые уже есть. Однако это справедливо только для неабстрактных методов. Если вы добавляете абстрактные методы, они все равно должны быть реализованы в каждом производном классе. Но, тем не менее, это может сделать вашу жизнь проще, если у вас есть API, который все еще развивается, и на нем уже есть много материала.

6 голосов
/ 15 мая 2010

Если вы добавляете метод с реализацией по умолчанию к абстрактному классу, ничего не нужно менять ни в каких производных классах.

В качестве альтернативы, если вы добавляете метод к интерфейсу, любые классы, реализующие этот интерфейс, должны реализовать метод - иначе они не будут компилироваться.

1 голос
/ 14 марта 2012

Пожалуйста, обратитесь также к следующим руководствам Eclipse Wiki

Развивающиеся API на основе Java

Добавление метода API

Пример 4. Добавление метода API

Может ли добавление метода API к классу или интерфейсу нарушить совместимость с существующими клиентами?

Если метод добавлен в интерфейс, который могут реализовать клиенты, то это определенно серьезное изменение.

Если метод добавлен в класс (интерфейс), который Клиентам не разрешено подклассировать (реализовать), то это не является критическим изменением.

Однако, если метод добавляется в класс, который клиенты могут подклассить, то изменение обычно следует рассматривать как критическое изменение. Причина этого резкого вывода заключается в том, что у подкласса Клиента уже есть собственная реализация метода с таким именем. Добавление метода API к суперклассу подрывает код Клиента, поскольку было бы явным совпадением, если бы существующий метод Клиента встречал контракт API нового добавленного метода. На практике, если вероятность совпадения имен такого рода достаточно низка, такого рода изменения часто трактуются так, как если бы они были неразрывными.

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