Когда использовать интерфейс вместо абстрактного класса и наоборот? - PullRequest
390 голосов
/ 26 января 2009

Это может быть общий вопрос ООП. Я хотел сделать общее сравнение между интерфейсом и абстрактным классом на основе их использования.

Когда нужно использовать интерфейс и когда нужно использовать абстрактный класс ?

Ответы [ 22 ]

4 голосов
/ 13 декабря 2014

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

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

  • Если вы планируете создать несколько версий вашего компонента, создайте абстрактный класс. Абстрактные классы предоставляют простой и легкий способ создания версий ваших компонентов. При обновлении базового класса все наследующие классы автоматически обновляются с изменением. Интерфейсы, с другой стороны, не могут быть изменены после создания таким образом. Если требуется новая версия интерфейса, вы должны создать совершенно новый интерфейс.
  • Если создаваемая вами функциональность будет полезна для широкого спектра разнородных объектов, используйте интерфейс. Абстрактные классы следует использовать в первую очередь для объектов, которые тесно связаны, тогда как интерфейсы лучше всего подходят для предоставления общих функций несвязанным классам.
  • Если вы разрабатываете небольшие, лаконичные кусочки функциональности, используйте интерфейсы. Если вы разрабатываете большие функциональные блоки, используйте абстрактный класс.
  • Если вы хотите обеспечить общую, реализованную функциональность среди всех реализаций вашего компонента, используйте абстрактный класс. Абстрактные классы позволяют вам частично реализовать ваш класс, тогда как интерфейсы не содержат реализации для каких-либо членов.

Скопировано из:
http://msdn.microsoft.com/en-us/library/scsyfw1d%28v=vs.71%29.aspx

3 голосов
/ 16 октября 2018

Когда предпочитать абстрактный класс интерфейсу?

  1. Если планируется обновление базового класса в течение жизни программы / проекта, лучше всего разрешить, чтобы базовый класс был абстрактным классом
  2. Если кто-то пытается создать магистраль для объектов, тесно связанных в иерархии, очень полезно использовать абстрактный класс

Когда предпочитать интерфейс над абстрактным классом?

  1. Если не иметь дело с массивным иерархическим типом фреймворка, интерфейс будет отличным выбором
  2. Поскольку множественное наследование не поддерживается с абстрактными классами (проблема с бриллиантами), интерфейсы могут сэкономить время
3 голосов
/ 21 апреля 2017

Рассмотрите возможность использования абстрактных классов , если любое из этих утверждений применимо к вашей ситуации:

  1. Вы хотите поделиться кодом между несколькими тесно связанными классами.
  2. Вы ожидаете, что классы, которые расширяют ваш абстрактный класс, имеют много общих методов или полей или требуют модификаторов доступа, кроме public (например, protected и private).
  3. Вы хотите объявить нестатические или не финальные поля. Это позволяет вам определять методы, которые могут обращаться и изменять состояние объекта, к которому они принадлежат.

Рассмотрите возможность использования интерфейсов , если любое из этих утверждений применимо к вашей ситуации:

  1. Вы ожидаете, что несвязанные классы будут реализовывать ваш интерфейс. Например, интерфейсы Comparable и Cloneable реализованы многими несвязанными классами.
  2. Вы хотите указать поведение определенного типа данных, но не беспокоитесь о том, кто реализует его поведение.
  3. Вы хотите воспользоваться множественным наследованием.

Источник

2 голосов
/ 26 января 2009

Ответы различаются в зависимости от языка. Например, в Java класс может реализовывать (наследовать) несколько интерфейсов, но наследовать только от одного абстрактного класса. Таким образом, интерфейсы дают вам больше гибкости. Но это не так в C ++.

2 голосов
/ 03 июня 2016

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

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

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

1 голос
/ 26 января 2009

Используйте абстрактный класс, если вы хотите предоставить некоторые базовые реализации.

1 голос
/ 26 января 2009

Чисто на основе наследования, вы бы использовали реферат, где вы определяете явно наследуемые, абстрактные отношения (т.е. animal-> cat) и / или требуете наследования виртуальных или закрытых свойств , особенно совместно используемое состояние (которое интерфейсы не могут поддерживать).

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

1 голос
/ 26 января 2009

Одно интересное место, где интерфейсы работают лучше, чем абстрактные классы, - это когда вам нужно добавить дополнительную функциональность в группу (связанных или не связанных) объектов. Если вы не можете дать им базовый абстрактный класс (например, они sealed или уже имеют родителя), вы можете вместо этого дать им фиктивный (пустой) интерфейс, а затем просто написать методы расширения для этого интерфейса.

1 голос
/ 26 января 2009

в Java вы можете наследовать от одного (абстрактного) класса для «обеспечения» функциональности, и вы можете реализовать множество интерфейсов для «обеспечения» функциональности

0 голосов
/ 26 января 2009

Это может быть очень сложный вызов ...

Один указатель, который я могу дать: объект может реализовывать много интерфейсов, в то время как объект может наследовать только один базовый класс (в современном языке OO, таком как c #, я знаю, что C ++ имеет множественное наследование - но разве это не осуждается?)

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