Есть ли сценарий, когда абстрактный класс предпочтительнее интерфейса - PullRequest
7 голосов
/ 23 июня 2011

У меня есть сценарий, в котором есть несколько подклассов, которые имеют похожие реализации, и некоторые дополнительные методы, для которых реализации отличаются для каждого подкласса.Я предполагаю, что абстрактный класс был бы хорошим выбором для этого сценария.Но было бы лучше, если бы этот абстрактный класс реализовывал интерфейс, который содержит все объявления методов. Или я должен просто придерживаться абстрактного класса.

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

Ответы [ 6 ]

5 голосов
/ 23 июня 2011

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

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

5 голосов
/ 23 июня 2011

Используйте абстрактный класс, если у ваших подклассов есть связь is-with с абстрактным классом.

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

Примером является структура коллекций - она ​​имеет ArrayList extends AbstractList implements List

3 голосов
/ 23 июня 2011

Абстрактный класс может обеспечивать поведение по умолчанию, где Интерфейсы не могут. Это имеет смысл, когда часть поведения будет распространена среди нескольких подклассов.

Очень хорошим примером является шаблонный метод: http://en.wikipedia.org/wiki/Template_method_pattern, который уменьшает последовательную связь.

1 голос
/ 23 июня 2011

Помните, что с помощью класса Abstract вы можете определять данные, которые имеют подклассы.С интерфейсом вы можете определять только те методы, которые должны реализовывать разработчики.Итак, в вашей ситуации вам нужны общие данные и общие методы или просто общие методы?

0 голосов
/ 23 июня 2011

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

0 голосов
/ 23 июня 2011

Абстрактные классы позволяют переносить код / ​​данные, которые затем можно использовать в унаследованных классах. Они отлично подходят для этого, но очень редко используют наследование. Наследуйте от класса только в том случае, если новый класс абсолютно взаимозаменяем с абстрактным.

Интерфейсы не содержат кода.

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

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

Вы можете применить интерфейс (или несколько небольших интерфейсов) к абстрактному классу. Похоже, это может быть вашим лучшим подходом.

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