Интерфейс против абстрактного класса (общий ОО)

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

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

Интерфейс:

Каждый метод, объявленный в интерфейсе, должен быть реализован в подклассе. В интерфейсе могут существовать только события, делегаты, свойства (C #) и методы. Класс может реализовывать несколько интерфейсов.

Абстрактный класс:

Только абстрактные методы должны быть реализованы подклассом. Класс Abstract может иметь нормальные методы с реализациями. Абстрактный класс может также иметь переменные класса, кроме событий, делегатов, свойств и методов. Класс может реализовать только один абстрактный класс только из-за отсутствия Multi-наследования в C #.

  1. После всего этого интервьюер задал вопрос: «Что если бы у вас был класс Abstract только с абстрактными методами? Чем бы он отличался от интерфейса?» Я не знал ответа, но я думаю, что это наследство, как упомянуто выше, верно?

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

Смотрите также :

17.04.2009 16:42:38
Хотя я думаю, что важно знать разницу между ними, это не очень хороший вопрос для интервью. Если только работа не была написанием книги по ОО темам. Тебе лучше не работать на этих динь летучих мышей.
Alan 17.04.2009 16:50:30
@ Алан: Мне действительно нравится это как вопрос для интервью, но я бы не стал об этом кого-то преследовать - вероятно, я бы опубликовал это больше как «Где бы вы выбрали интерфейс вместо абстрактного базового класса при определении иерархии? или что-то подобное.
Reed Copsey 17.04.2009 17:00:35
Может быть, они хотели получить более сфокусированный ответ ... хотя, как и вы, я бы отнесся к этому как к техническому вопросу.
CurtainDog 19.01.2010 06:32:41
Хорошие табличные различия здесь: mindprod.com/jgloss/interfacevsabstract.html
Rajat_R 1.02.2013 03:38:15
@Kave: I insisted you can't have a public variable inside an interface.я думаю, что интерфейс может иметь открытую переменную. Фактически переменные в интерфейсе автоматически становятся открытыми и окончательными.
a Learner 5.07.2013 11:30:56
30 ОТВЕТОВ
РЕШЕНИЕ

Хотя ваш вопрос указывает на то, что он относится к «общепринятым нормам», похоже, он действительно фокусируется на использовании этих терминов .NET

В .NET (аналогично для Java):

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

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

Действительно, существует идиома C ++, называемая не-виртуальным интерфейсом (NVI), где открытые методы - это не виртуальные методы, которые «одобряются» для частных виртуальных методов:

740
10.09.2013 03:41:31
Спасибо. Я думаю, что поскольку в вашем ответе упоминается состояние + хороший обзор всего остального, я отмечаю ваш ответ как окончательный ответ. Вы правы, я попросил генерального OO, так как мой первый интервьюер попросил генерального OO, но так как я парень на C #, я склонен забывать об этом. ;-) Также спасибо за объяснение C ++, как всегда, C ++ просто сногсшибателен.
Houman 17.04.2009 17:34:08
Я думаю, что ключевой момент в объяснении Майкла состоит в том, что при реализации интерфейса вы ДОЛЖНЫ реализовывать все члены интерфейса, но при наследовании от абстрактного класса дочернему классу НЕ ТРЕБУЕТСЯ реализовывать члены его родителя
Guillermo Gomez 2.03.2010 21:12:59
+1: я был бы готов поспорить, что эти обезьяны, проводящие интервью, даже не понимают, что другие языки реализуют ОО по-другому.
Lightness Races in Orbit 11.01.2012 10:49:11
@JL Я не понимаю, в чем проблема. Вы, кажется, перепутали абстрактный метод с абстрактным классом. Абстрактные методы не имеют реализации. Однако, внутри абстрактного класса , некоторые методы могут быть абстрактными (т.е. без реализации) в то время как некоторые другие могут действительно иметь реализацию.
xji 30.04.2014 04:05:27
Обратите внимание, что в Java 8 теперь вы можете иметь методы по умолчанию и статические методы в интерфейсах, что означает, что интерфейсы Java могут иметь реализацию. Ссылка здесь . Очевидно, вы ссылались в основном на .NET, так что это всего лишь наблюдение, относящееся к Java.
davtom 1.07.2014 13:24:34

Есть несколько других отличий -

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

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

Абстрактные базовые классы могут быть изменены в v2 + без нарушения API. Изменения в интерфейсах разрушают изменения.

[C # /. NET Specific] Интерфейсы, в отличие от абстрактных базовых классов, могут применяться к типам значений (структурам). Структуры не могут наследоваться от абстрактных базовых классов. Это позволяет применять поведенческие контракты / инструкции по использованию к типам значений.

77
17.04.2009 16:58:46
+1 за ключевой момент, что в классе может быть реализовано более одного интерфейса.
cgp 17.04.2009 16:50:22
Это единственное реальное преимущество интерфейсов перед абстрактными базовыми классами, IMO. В противном случае, я согласен с рекомендациями по проектированию .NET, которые теперь говорят «предпочесть абстрактные базовые классы интерфейсам»
Reed Copsey 17.04.2009 16:51:14
Хотя было бы интересно, если бы вы добавили, что его интерфейсы можно применять к любому классу.
cgp 17.04.2009 16:52:03
@altCognito: понял, что это вроде как со вторым абзацем. Это напомнило мне, однако, что интерфейсы работают с типами значений, поэтому я добавил это.
Reed Copsey 17.04.2009 16:59:16
Большое спасибо за это точное описание. Это действительно очень полезно. Я новенький здесь. Жаль, что вы не можете выбрать два ответа как «ответ». Меня смущает то, что вы используете абстрактный базовый класс. Все абстрактные классы должны быть базовым классом подкласса. Зачем называть «базовый» дополнительный?
Houman 17.04.2009 17:20:22

Для .Net,

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

РЕДАКТИРОВАТЬ: С другой стороны, я бы даже не использовал фразу «подкласс» (или фразу «наследование») для описания классов, которые «определены для реализации» интерфейса. Для меня интерфейс - это определение контракта, которому должен соответствовать класс, если он определен для «реализации» этого интерфейса. Это ничего не наследует ... Вы должны сами все добавить, явно.

21
17.04.2009 16:53:12
Да! Государственный! Вот что имел в виду второй интервьюер со своим странным способом сказать «публичная переменная» внутри интерфейса. Гоша! Абстрактные классы могут иметь состояние, интерфейсы - нет! И да, все остальные также согласны с различиями в способах наследования, о которых я забыл упомянуть, но выяснил это уже позже. :) Спасибо всем!
Houman 17.04.2009 17:11:04
Больше, чем просто состояние ... Абстрактные классы могут иметь РЕАЛИЗАЦИЮ. то есть у них могут быть методы с кодом, который на самом деле выполняется и выполняет что-то, что наследуется и выполняется экземплярами базовых классов ... Не так с интерфейсами
Charles Bretana 10.03.2011 15:51:17
Более того, в каком-то смысле абстрактные классы МОГУТ быть созданы, их просто нужно создавать, используя определение производного класса, а не напрямую. Но переменные состояния, определенные в абстрактном классе, создаются в объекте, созданном путем обновления экземпляра производного класса. Этот экземпляр является экземпляром абстрактного класса, а также является экземпляром производного класса - в конце концов, он является производным от него. Ничто из этого не относится к интерфейсу.
Charles Bretana 6.12.2017 16:32:39
Когда вы создаете экземпляр класса, определенного для реализации интерфейса, он не является «экземпляром» этого интерфейса, все, что делает синтаксис, - это заставляет компилятор проверять код для класса и гарантировать, что каждое поведение (метод, свойство , event, eventHandler и т. д.), который определяется интерфейсом, был реализован в коде для класса.
Charles Bretana 6.12.2017 16:35:29

Интервьюеры лают странное дерево. Для языков, таких как C # и Java, есть разница, но в других языках, таких как C ++, нет. Теория ОО не различает их, а только синтаксис языка.

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

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

33
17.04.2009 16:48:06
Мне задали тот же вопрос неделю назад, у меня нет опыта работы с Java, но я уже некоторое время работаю с C ++. Интервьюер не указывал языки перед тем, как задавать вопрос, поэтому я просто объяснил, что интерфейсы в этом случае были абстрактными классами без состояний или реализаций любого рода. Я согласен, что это тоже странный вопрос.
dacabdi 27.09.2017 12:45:30

Из другого моего ответа , в основном касающегося того, когда использовать один против другого:

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

6
23.05.2017 11:55:03

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

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

Например:

  public interface IVariable
  {
      string name {get; set;}
  }

Класс, реализующий этот интерфейс, должен иметь такое свойство.

7
11.01.2012 10:50:37

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

31
17.04.2009 16:52:42
Интерфейсы достигают, IMO, больше отношения "Acts-as-a". Инкапсуляция позволяет добиться композиции лучше, чем интерфейс.
Reed Copsey 17.04.2009 17:01:25
Я не думаю, что реализация интерфейсов была бы под композицией.
Pavan Dittakavi 7.12.2012 20:49:39
Кроме того, интерфейс более вероятно использовать для описания «возможностей», таких как IDisposable. Раньше он разделял функциональность между классами, чтобы эти классы могли что-то делать. Еще пример IFlyable может быть реализован птицей и самолетом. Но Bird может происходить от Class Creature, где воздушные суда происходят от AirCraft.
Peter.Wang 30.08.2016 07:26:34

Ответ на второй вопрос: publicпеременная, определенная в interface, static finalпо умолчанию, тогда как publicпеременная в abstractклассе является переменной экземпляра.

6
29.05.2017 17:07:56

Интерфейсы - это легкий способ реализации определенного поведения. Это один из способов думать.

9
19.01.2010 05:48:26

Пара других отличий:

Абстрактные классы могут иметь статические методы, свойства, поля и т. Д. И операторы, интерфейсы не могут. Оператор приведения допускает приведение к / из абстрактного класса, но не разрешает приведение к / из интерфейса.

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

3
12.05.2010 22:10:56
в Java интерфейс может иметь переменную-член, но по умолчанию они становятся общедоступными статическими. Поэтому интерфейс может иметь статические поля
Jitendra Vispute 10.06.2013 11:12:38
Да, интерфейс может иметь статические поля. НО интерфейс не может иметь статических методов.
a Learner 5.07.2013 11:42:40

Как насчет аналогии: когда я был в ВВС, я прошел подготовку пилотов и стал пилотом ВВС США (ВВС США). В тот момент у меня не было квалификации, чтобы летать, и я должен был проходить обучение по типу самолета. После того, как я получил квалификацию, я был пилотом (абстрактный класс) и пилотом C-141 (конкретный класс). На одном из моих заданий мне дали дополнительную обязанность: офицер безопасности. Теперь я был еще пилотом и пилотом C-141, но я также выполнял обязанности сотрудника по безопасности (я, так сказать, реализовал ISafetyOfficer). Пилот не должен был быть офицером безопасности, другие люди тоже могли это сделать.

Все пилоты ВВС США должны следовать определенным правилам военно-воздушных сил, а все пилоты C-141 (или F-16, или T-38) являются «пилотами ВВС США». Любой может быть офицером безопасности. Итак, подведем итог:

  • Пилот: абстрактный класс
  • C-141 Pilot: класс бетона
  • Сотрудник по безопасности: интерфейс

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

861
19.01.2015 11:04:09
Мне очень нравится эта аналогия, она использует простой пример, чтобы объяснить немного сложную тему
Kevin Bowersox 7.01.2012 16:37:27
Это лучший способ понять сложную терминологию ОО. Короче говоря, вся теория имеет смысл только тогда, когда вы можете использовать ее практически. @ Джей, ты, например, действительно легко понять несколько пунктов пули (в основном пронизывающий разум вместо того, чтобы быть поглощенным!)
v s 20.09.2012 08:56:32
Я все еще немного смущен. Скажем, теперь вы получили квалификации F-16 и T-38, поэтому теперь класс Jayне может наследоваться от нескольких классов (пилот C-141, пилот F-16 и пилот T-38), означает ли это, что чьи классы должны стать интерфейсами? Спасибо
Alex Okrushko 30.01.2013 15:31:42
Многие люди справедливо дали +1 к комментарию Алекса, поскольку он показывает некоторую слабость в этом примере. Во-первых, я бы сказал, что Джей будет экземпляром C-141Pilot, а не его собственным классом. Кроме того, поскольку в ВВС США 99% всех пилотов одновременно квалифицируются только на одном самолете (за исключением FCF и тестовых пилотов), я не рассматривал множественные квалификации и способы их реализации. Как я знаю о пилоте, который 50 лет назад был одновременно квалифицирован в 25 различных самолетах, я думаю, это иллюстрирует то, как мы НЕ хотим использовать множественное наследование.
Jay 16.07.2013 05:51:48
Поскольку маловероятно, что один пилот будет летать одновременно более чем на одном самолете, это будет хорошей возможностью для реализации стратегии. Пилот будет иметь коллекцию сертификатов и выбрать правильный во время выполнения. Сертификаты будут кодироваться как поведения, которые будут реализовывать интерфейс IFlyPlane с методами TakeOff, Land, Eject.
Michael Blackburn 22.12.2013 06:25:02

Я думаю, что ответ, который они ищут, - это фундаментальное или философское различие OPPS.

Наследование абстрактного класса используется, когда производный класс разделяет основные свойства и поведение абстрактного класса. Тип поведения, который на самом деле определяет класс.

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

Например, Автомобиль и Грузовик имеют много основных свойств и поведения абстрактного класса Automobile, но они также имеют некоторое периферийное поведение, такое как Генерация выхлопа, которое разделяют даже не автомобильные классы, такие как Drillers или PowerGenerators, и не обязательно определяют Автомобиль или Грузовик. Таким образом, Car, Truck, Driller и PowerGenerator могут использовать один и тот же интерфейс IExhaust.

220
31.08.2011 12:09:43
Я думаю, что еще лучшая аналогия была бы «использует топливо», которая показала бы контрактную природу интерфейса.
Pureferret 4.09.2012 12:15:10
@Pureferret, если accelerateявляется частью основного поведения абстрактного класса Automobile, то я не могу сказать, что accelerateпоказывает характер контракта . что такое контрактный характер? почему это слово contractвводится всякий раз, когда мы говорим о interface?
overexchange 11.11.2014 18:44:59
@overexchange, потому что обычно интерфейс - это место, где встречаются две «поверхности», но слово «контракт» подразумевает, что существует соглашение о том, как встречаются две «поверхности». Не имеет смысла (по крайней мере для меня), что генерация выхлопных газов - это то, с чем вы «соглашаетесь». Но имеет смысл (опять же для меня), что вы можете договориться о необходимости использовать топливо.
Pureferret 12.11.2014 13:27:56
@Pureferret Я поднял запрос по ссылке для того же
overexchange 13.11.2014 07:28:22
@Pureferret Если interfaceнеобходимо иметь периферийное поведение, то почему public interface List<E> extends Collection<E> {}он предназначен для описания основного поведения list? это на самом деле противоречит ответу прасуна. Оба Collection<E>и List<E>здесь интерфейсы.
overexchange 13.11.2014 15:51:34
  1. Интерфейс:
    • Мы не реализуем (или не определяем) методы, мы делаем это в производных классах.
    • Мы не объявляем переменные-члены в интерфейсах.
    • Интерфейсы выражают отношения HAS-A. Это означает, что они являются маской объектов.
  2. Абстрактный класс:
    • Мы можем объявлять и определять методы в абстрактном классе.
    • Мы скрываем конструкторы этого. Это означает, что нет никакого объекта, созданного из этого непосредственно.
    • Абстрактный класс может содержать переменные-члены.
    • Производные классы наследуются от абстрактного класса, что означает, что объекты из производных классов не маскируются, а наследуются от абстрактного класса. Отношения в этом случае IS-A.

Это мое мнение.

13
8.04.2014 11:39:30

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

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

2- Интерфейс - это контракт, полная бизнес-функциональность, представленная одним или несколькими наборами функций. Вот почему он реализован, а не наследуется. Бизнес-объект (часть иерархии или нет) может иметь любое количество полных бизнес-функций. Это не имеет ничего общего с абстрактными классами, означает наследование в целом. Например, человек может запустить, слон может выполнить, птица может выполнить и т. Д., Все эти объекты различной иерархии будут реализовывать интерфейс RUN или интерфейс EAT или SPEAK. Не входите в реализацию, поскольку вы можете реализовать ее как наличие абстрактных классов для каждого типа, реализующего эти интерфейсы. Объект любой иерархии может иметь функциональность (интерфейс), которая не имеет ничего общего с его иерархией.

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

Когда вас спрашивают о разнице, это фактически концептуальное различие, а не различие в реализации для конкретного языка, если не задано явно.

Я полагаю, что оба интервьюера ожидали однозначного различия между этими двумя, а когда вы потерпели неудачу, они пытались подтолкнуть вас к этому различию, внедрив ОДНОГО как ДРУГОЕ

Что если бы у вас был класс Abstract только с абстрактными методами?

26
10.03.2018 13:23:20
Это в значительной степени суммирует ответ на этот вопрос довольно хорошо.
pranavn 20.04.2018 11:37:25
реализована функциональность против расширенной структуры, приятно!
harshvchawla 29.08.2019 08:25:59

Коротко: Абстрактные классы используются для моделирования иерархии классов похожих классов (например, Animal может быть абстрактным классом, а Human, Lion, Tiger могут быть конкретными производными классами)

А ТАКЖЕ

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

198
5.04.2012 09:53:44
Мне действительно нравится этот ответ, потому что иногда трудно ответить на вопрос «что» отличается между вещами, рассматривая нечто более абстрактное, такое как намерение , а не только структуру (поскольку структурно интерфейс и чистый абстрактный класс почти одинаковы предмет).
LostSalad 19.08.2014 16:09:38
Легко перечислить, что абстрактный класс против интерфейса может делать на определенном языке, но сложнее создать абстракцию, чтобы придать объекту смысл и ответственность, а то, что вы сказали, полностью возобновляет использование концепции 2 в ОО. Спасибо!
Samuel 17.04.2017 23:59:27
@dhananjay: я вижу, как Высота может быть отделена от концепции класса Animal и может быть от другого другого класса, но что именно вы подразумеваете под "связью" между классами? Это просто определение высоты для своего класса, верно?
T.T.T. 12.02.2018 19:59:39

Хотя этот вопрос довольно старый, я хотел бы добавить еще один момент в пользу интерфейсов:

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

7
21.03.2014 08:36:55
Я полагаю, вы имеете в виду, что инструмент DI может внедрить класс, который реализует интерфейс. Некоторые такие инструменты могут также вводить классы, полученные из абстрактного класса, или вы говорите, что это невозможно?
John Saunders 31.08.2012 14:30:55

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

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Теперь велосипед ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

И автомобиль ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

Это все о наследовании . Мы используем их для классификации объектов на более простые формы Base и их потомков, как мы видели выше.

Абстрактные классы

Абстрактные классы являются неполными объектами. Чтобы понять это далее, давайте еще раз рассмотрим аналогию с автомобилем.
Транспортное средство можно вести. Правильно? Но разные транспортные средства управляются по-разному ... Например, вы не можете водить машину так же, как водите велосипед.
Итак, как представить функцию движения транспортного средства? Труднее проверить, что это за тип транспортного средства, и управлять им со своей функцией; вам придется менять класс водителя снова и снова при добавлении нового типа транспортного средства.
Здесь идет роль абстрактных классов и методов. Вы можете определить метод drive как абстрактный, чтобы сказать, что каждый наследующий потомок должен реализовать эту функцию.
Так что, если вы измените класс автомобиля ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

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

Интерфейсы Интерфейсы полностью неполные. У них нет никаких свойств. Они просто указывают, что наследующие дети способны что-то делать ...
Предположим, у вас есть разные типы мобильных телефонов. У каждого из них есть разные способы выполнять разные функции; Пример: позвонить человеку. Производитель телефона указывает, как это сделать. Здесь мобильные телефоны могут набирать номер, то есть он может набирать номер. Давайте представим это как интерфейс.

public interface Dialable {
    public void dial(Number n);
}

Здесь создатель Dialable определяет, как набрать номер. Вам просто нужно дать ему номер для набора.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Таким образом, используя интерфейсы вместо абстрактных классов, разработчику функции, которая использует Dialable, не нужно беспокоиться о его свойствах. Пример: есть ли у него сенсорный экран или клавиатура, стационарный телефон или мобильный телефон. Вам просто нужно знать, можно ли набрать номер; наследует ли (или реализует) интерфейс Dialable.

И что еще более важно , если когда-нибудь вы переключите Dialable с другим

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

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

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

Больше информации Абстрактные классы и интерфейсы

67
10.03.2018 16:04:14
Это неправда, что «Интерфейсы не имеют никаких свойств».
Bigeyes 29.05.2017 20:06:29
@Bigeyes, Java не позволяет свойства в интерфейсах. Я думал, что то же самое было и в других языках. Не могли бы вы объяснить подробнее?
fz_salam 29.05.2017 23:53:30
Я имею в виду C # /. Net. Пожалуйста , смотрите пример
Bigeyes 30.05.2017 00:11:10
@Bigeyes для C #, где интерфейсы могут иметь свойства, разве это не вызывает проблему множественного наследования? Что происходит, когда класс использует несколько интерфейсов, которые определили одно и то же свойство? Просто любопытно спасибо
stackPusher 21.12.2017 05:01:08
@happycoder: re: "Здесь, используя интерфейсы вместо абстрактных классов, вам не нужно беспокоиться о его свойствах. Например: есть ли у него сенсорный экран или клавиатура, стационарный или мобильный телефон. Вам просто нужно знать, является ли он набираемым; наследует ли он (или реализует) интерфейс Dialable. " - Можете ли вы показать это в примере кода, также не видел, как это будет унаследовано ...
T.T.T. 12.02.2018 21:33:01
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

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

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Переменные в интерфейсах по умолчанию являются общедоступными static и final. Вопрос может быть сформулирован так, как если бы все переменные в абстрактном классе были публичными? Ну, они все еще могут быть не статичными и не финальными в отличие от переменных в интерфейсах.

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

13
20.08.2013 12:34:23

Interface:- == contract.Whichever класс реализует это должно следовать всей спецификации интерфейса.

Примером в реальном времени будет любой ISOпомеченный продукт. ISOдает набор rules/specificationо том, как продукт должен быть построен и что у minimum set of featuresнего Mustесть.

Это всего лишь subset of propertiesпродукт, который должен быть. ISO подпишет продукт only if it satisfies the its standards.

Теперь взгляните на этот код

public interface IClock{       //defines a minimum set of specification which a clock should have

    public abstract Date getTime();
    public abstract int getDate();
}
public class Fasttrack: Clock {
    // Must have getTime() and getTime() as it implements IClock
    // It also can have other set of feature like 
    public void startBackgroundLight() {
        // watch with internal light in it.
    }
    .... //Fastrack can support other feature as well
    ....
    ....
}

Здесь a Fastrackназывается watch, потому что it has all that features that a watch must suppost( минимальный набор функций ).

Почему и когда Аннотация:

Из MSDN:

Цель abstract classсостоит в том, чтобы предоставить доступ к common definition of a base classнескольким производным классам.

Например, библиотека классов может определять абстрактный класс, который используется в качестве параметра для многих его функций, и требовать от программистов, использующих эту библиотеку, обеспечения своей собственной реализации класса путем создания производного класса. Abstract simply means if you cannot define it completely declare it as an abstractКласс .Implementing завершит эту реализацию.

Например: предположим, что я объявляю класс Recipeабстрактным, но я не знаю, какой рецепт будет сделан. Затем я обобщу этот класс для определения common definition of any recipe. Внедрение рецепта будет зависеть от реализации блюда.

Абстрактный класс может состоять как из абстрактных методов, так и из не абстрактных методов. Таким образом, вы можете заметить разницу в Interface.Так не обязательно каждый метод должен иметь ваш реализующий класс. Вам нужно только переопределить абстрактные методы.

Простыми словами, если вы хотите tight coupling use Interface o/w use in case of lose coupling Abstract Class

3
12.09.2013 15:22:47

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

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

Заметьте, C # также допускает наследование интерфейса.

10
4.10.2013 21:11:14
Использование терминов « горизонтальный» и « вертикальный» позволило очень четко представить разницу.
Infinity 24.01.2018 08:09:18

С точки зрения кодирования

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

С точки зрения дизайна

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

Решите, что вам нужно: только применение политики или повторное использование кода и политика.

5
6.03.2016 21:16:51

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

Интерфейс представляет собой соглашение . Там указано: «так мы будем разговаривать». Он не может иметь никакой реализации, потому что он не должен иметь никакой реализации. Это контракт. Это как .hзаголовочные файлы в C.

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

По сути, любой класс, абстрактный или нет, - это то, чем он является , а интерфейс - как вы его используете . Например: Animalможет быть абстрактный класс, реализующий некоторые основные метаболические функции и задающий абстрактные методы для дыхания и передвижения без предоставления реализации, потому что он не знает, должен ли он дышать через жабры или легкие, и летит ли он, плавает, гуляет или ползает. Mountс другой стороны, это может быть интерфейс, который указывает, что вы можете ездить на животном, не зная, какое это животное (или вообще это животное!).

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

10
8.04.2014 12:07:21

Скопировано из CLR через C # Джеффри Рихтером ...

Я часто слышу вопрос: «Должен ли я проектировать базовый тип или интерфейс?» Ответ не всегда однозначен.

Вот несколько рекомендаций, которые могут вам помочь:

■■ Соотношение IS-A и CAN-DO Тип может наследовать только одну реализацию. Если производный тип не может требовать отношения IS-A с базовым типом, не используйте базовый тип; использовать интерфейс. Интерфейсы подразумевают связь CAN-DO. Если кажется, что функциональность CAN-DO относится к различным типам объектов, используйте интерфейс. Например, тип может преобразовывать свои экземпляры в другой тип (IConvertible), тип может сериализовать свой экземпляр (ISerializable) и т. Д. Обратите внимание, что типы значений должны быть получены из System.ValueType, и, следовательно, они не могут быть получены из произвольного базового класса. В этом случае вы должны использовать отношение CAN-DO и определить интерфейс.

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

■■ Последовательная реализация Независимо от того, насколько хорошо документирован контракт интерфейса, очень маловероятно, что каждый будет выполнять контракт на 100 процентов правильно. Фактически, COM страдает от этой самой проблемы, поэтому некоторые COM-объекты корректно работают только с Microsoft Word или Windows Internet Explorer. Предоставляя базовый тип с хорошей реализацией по умолчанию, вы начинаете с использования типа, который работает и хорошо протестирован; затем вы можете изменить детали, которые нуждаются в модификации.

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

12
21.04.2014 19:34:47
@AbdullahShoaib - это может быть кто угодно, но не может сделать, здесь есть разница. это основная причина, нам нужен интерфейс. поведение can-do также будет частью abstract class.
overexchange 13.11.2014 17:24:25

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

  1. Когда мы должны использовать интерфейс?

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

  2. Когда мы должны использовать абстрактный класс?

    если вы знаете реализацию, но не полностью (частично реализацию), тогда мы идем с классом Abstract.

    Интерфейс

    каждый метод по умолчанию public abstract означает, что интерфейс на 100% чистый аннотация.

    Аннотация

    может иметь метод Concrete и метод Abstract, то есть метод Concrete, который имеет реализацию в классе Abstract. Абстрактный класс - это класс, который объявлен как абстрактный - он может включать или не включать абстрактные методы.

    Интерфейс

    Мы не можем объявить интерфейс как частный, защищенный

    В. Почему мы не объявляем интерфейс закрытым и защищенным?

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

    Метод интерфейса
    также мы не можем объявить интерфейс как частный, защищенный, окончательный, статический, синхронизированный, родной .....

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

    Аннотация

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

    Интерфейс

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

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

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

    Аннотация

    Абстрактная переменная не нуждается в объявлении public static final.

Я надеюсь, что эта статья полезна.

26
12.06.2015 04:55:55
Я не согласен с этим: Abstract class must have at lease one abstract method.возможно иметь класс Abstract без метода Abstract, если вы его реализуете. СПРАВКА: An abstract class is a class that is declared abstract—it may or may not include abstract methods.СПРАВОЧНЫЙ ИСТОЧНИК: docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Devner 2.12.2014 07:10:21
Вы говорите о технических деталях и реализации, вы не отвечаете на вопрос с точки зрения общего ООП
Billal Begueradj 18.08.2018 07:14:57

Интерфейс : должен использоваться, если вы хотите наложить правило на компоненты, которые могут или не могут быть связаны друг с другом

Плюсы:

  1. Позволяет множественное наследование
  2. Обеспечивает абстракцию, не раскрывая, какой именно тип объекта используется в контексте
  3. обеспечивает согласованность конкретной подписью контракта

Минусы:

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

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

Плюсы:

  1. Быстрее, чем интерфейс
  2. Имеет гибкость в реализации (вы можете реализовать ее полностью или частично)
  3. Может быть легко изменено, не нарушая производные классы

Минусы:

  1. Не может быть создан
  2. Не поддерживает множественное наследование
20
15.07.2018 18:22:41
Определить быстрее. Это важно? Что это вообще значит? код операции для вызова функции в абстрактном классе быстрее, чем код операции для вызова функции в интерфейсе?
denis631 11.02.2020 17:38:59
@ denis631 абстрактный класс немного быстрее интерфейса из-за поиска и вызова в интерфейсе метода. Прочитайте этот coderanch.com/t/503450/java/abstract-class-faster-interface
bourax webmaster 12.02.2020 18:12:28

Типы интерфейса и абстрактные базовые классы

Адаптировано из Pro C # 5.0 и книги .NET 4.5 Framework .

Тип интерфейса может показаться очень похожим на абстрактный базовый класс. Напомним, что когда класс помечен как абстрактный, он может определять любое количество абстрактных членов, чтобы обеспечить полиморфный интерфейс для всех производных типов. Однако даже когда класс определяет набор абстрактных членов, он также может свободно определять любое количество конструкторов, полевых данных, неабстрактных членов (с реализацией) и так далее. Интерфейсы, с другой стороны, содержат только абстрактные определения членов. Полиморфный интерфейс, созданный абстрактным родительским классом, страдает одним серьезным ограничением в том, что только производные типы поддерживают члены, определенные абстрактным родительским классом. Однако в более крупных программных системах очень часто разрабатываются множественные иерархии классов, у которых нет общего родителя, кроме System.Object. Учитывая, что абстрактные члены в абстрактном базовом классе применяются только к производным типам, у нас нет способа настроить типы в разных иерархиях для поддержки одного и того же полиморфного интерфейса. В качестве примера предположим, что вы определили следующий абстрактный класс:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Учитывая это определение, только члены, расширяющие CloneableType, могут поддерживать метод Clone (). Если вы создадите новый набор классов, которые не расширяют этот базовый класс, вы не сможете получить этот полиморфный интерфейс. Также вы можете вспомнить, что C # не поддерживает множественное наследование классов. Поэтому, если вы хотите создать MiniVan, который является автомобилем и является CloneableType, вы не можете сделать это:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Как вы уже догадались, на помощь приходят типы интерфейсов. После того, как интерфейс был определен, он может быть реализован любым классом или структурой, в любой иерархии, в любом пространстве имен или любой сборке (написанной на любом языке программирования .NET). Как видите, интерфейсы очень полиморфны. Рассмотрим стандартный интерфейс .NET с именем ICloneable, определенный в пространстве имен System. Этот интерфейс определяет единственный метод с именем Clone ():

public interface ICloneable
{
object Clone();
}
6
29.08.2014 23:29:10

Поскольку вы, возможно, получили теоретические знания от экспертов, я не буду тратить много слов на повторение всего этого здесь, а позвольте мне объяснить на простом примере, где мы можем использовать / не можем использовать Interfaceи Abstract class.

Предположим, вы разрабатываете приложение, чтобы перечислить все функции автомобилей. В разных точках вам необходимо общее наследование, так как некоторые свойства, такие как DigitalFuelMeter, кондиционер, регулировка сиденья и т. Д., Являются общими для всех автомобилей. Точно так же нам нужно наследование только для некоторых классов, поскольку некоторые свойства, такие как тормозная система (ABS, EBD), применимы только для некоторых автомобилей.

Нижеследующий класс выступает в качестве базового класса для всех автомобилей:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Представьте, что у нас есть отдельный класс для каждой машины.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Предположим, нам нужен метод наследования технологии торможения для автомобилей Verna и Cruze (неприменимо для Alto). Хотя оба используют технологию торможения, «технология» отличается. Итак, мы создаем абстрактный класс, в котором метод будет объявлен как Abstract, и он должен быть реализован в его дочерних классах.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Сейчас мы пытаемся унаследовать от этого абстрактного класса, и тип системы торможения реализован в Verna и Cruze:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

Видите проблему в двух вышеупомянутых классах? Они наследуются от нескольких классов, которые C # .Net не позволяет, хотя метод реализован в дочерних элементах. Здесь приходит необходимость интерфейса.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

И реализация приведена ниже:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Теперь Verna и Cruze могут добиться множественного наследования с помощью собственных технологий торможения с помощью интерфейса.

10
13.04.2017 07:07:29
Это одно из лучших объяснений из-за примеров.
Adam Mendoza 26.07.2016 06:42:40
Это имеет смысл для меня, не ломая голову. Я просто пытался придумать пример автомобиля для моих учеников. Спасибо, что нашли время, чтобы собрать это вместе.
tazboy 20.01.2017 13:45:29

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

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

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

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

17
21.07.2015 07:18:47

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

Oracle сайт предоставляет основные различия между interfaceи abstractклассом.

Рассмотрите возможность использования абстрактных классов, если:

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

Рассмотрите возможность использования интерфейсов, если:

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

Проще говоря, я хотел бы использовать

интерфейс: для реализации контракта несколькими несвязанными объектами

абстрактный класс: для реализации одинакового или разного поведения среди нескольких связанных объектов

Взгляните на пример кода, чтобы ясно понять вещи: как мне объяснить разницу между интерфейсом и классом Abstract?

44
23.05.2017 10:31:37

Конечно, важно понимать поведение интерфейса и абстрактного класса в ООП (и как языки обрабатывают их), но я думаю, что также важно понимать, что именно означает каждый термин. Можете ли вы представить, что ifкоманда не работает точно как значение термина? Кроме того, на самом деле некоторые языки сокращают, даже больше, различия между интерфейсом и абстрактным ... если случайно однажды два термина работают почти одинаково, по крайней мере, вы можете сами определить, где (и почему) должен быть любой из них. используется для.

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

Интерфейс:

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

Аннотация:

Нечто, которое концентрирует в себе основные качества чего-то более обширного или более общего или нескольких вещей; сущность.

Пример:

Вы купили машину, и ей нужно топливо.

введите описание изображения здесь

Модель вашего автомобиля - XYZжанровая ABC, так что это конкретный автомобиль, конкретный экземпляр автомобиля. Автомобиль не настоящий объект. Фактически это абстрактный набор стандартов (качеств) для создания конкретного объекта. Короче говоря, Car - это абстрактный класс , это «то, что концентрирует в себе основные качества чего-то более обширного или более общего» .

Единственное топливо, которое соответствует спецификации автомобиля, должно использоваться для наполнения автомобильного бака. На самом деле, ничто не ограничивает вас в заправке топливом, но двигатель будет работать правильно только с указанным топливом, поэтому лучше следовать его требованиям. Требования говорят, что он принимает, как и другие автомобили того же жанра ABC, стандартный набор топлива.

В объектно-ориентированном представлении топливо для жанра ABCне должно быть объявлено как класс, потому что нет никакого конкретного топлива для определенного жанра автомобиля. Несмотря на то, что ваш автомобиль может принимать абстрактный класс «Fuel» или «AutularFuel», вы должны помнить, что только часть имеющегося у вас топлива для автомобилей соответствует спецификации, которая соответствует требованиям, изложенным в руководстве по эксплуатации вашего автомобиля. Короче говоря, они должны реализовать интерфейс ABCGenreFuel , который «... позволяет отдельным и иногда несовместимым элементам эффективно координировать» .

добавление

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

Учебный класс:

Количество людей или вещей, рассматриваемых как формирующие группу по причине общих признаков, характеристик, качеств или черт характера; вид;

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

6
13.03.2018 00:55:04
слишком много пуха, не делайте это звучит более запутанно для людей, чем это может быть.
ganjeii 2.12.2016 19:09:44