Недавно у меня было два телефонных интервью, где меня спрашивали о различиях между интерфейсом и абстрактным классом. Я объяснил каждый их аспект, который мог придумать, но, похоже, они ждут, чтобы я упомянул что-то конкретное, и я не знаю, что это такое.
Исходя из своего опыта, я думаю, что это правда. Если я не понял, пожалуйста, дайте мне знать.
Интерфейс:
Каждый метод, объявленный в интерфейсе, должен быть реализован в подклассе. В интерфейсе могут существовать только события, делегаты, свойства (C #) и методы. Класс может реализовывать несколько интерфейсов.
Абстрактный класс:
Только абстрактные методы должны быть реализованы подклассом. Класс Abstract может иметь нормальные методы с реализациями. Абстрактный класс также может иметь переменные класса, кроме событий, делегатов, свойств и методов. Класс может реализовать только один абстрактный класс только из-за отсутствия Multi-наследования в C #.
После всего этого интервьюер задал вопрос: «Что если бы у вас был класс Abstract только с абстрактными методами? Чем бы он отличался от интерфейса?» Я не знал ответа, но я думаю, что это наследство, как упомянуто выше, верно?
Другой интервьюер спросил меня, что если бы внутри интерфейса была переменная Public, как бы она отличалась от абстрактного класса? Я настаивал на том, чтобы внутри интерфейса не было публичной переменной. Я не знал, что он хотел услышать, но он тоже не был удовлетворен.
Смотрите также :
источник
I insisted you can't have a public variable inside an interface.
я думаю, что интерфейс может иметь открытую переменную. Фактически переменные в интерфейсе автоматически становятся открытыми и окончательными.Ответы:
Хотя ваш вопрос указывает на то, что он относится к «общепринятым нормам», похоже, что он действительно фокусируется на использовании этих терминов в .NET.
В .NET (аналогично для Java):
Как общие термины ОО, различия не обязательно четко определены. Например, есть программисты на C ++, которые могут иметь похожие жесткие определения (интерфейсы являются строгим подмножеством абстрактных классов, которые не могут содержать реализацию), в то время как некоторые могут сказать, что абстрактный класс с некоторыми реализациями по умолчанию все еще является интерфейсом или что неабстрактный класс все еще может определять интерфейс.
В действительности, существует идиома C ++, называемая не-виртуальным интерфейсом (NVI), где открытые методы - это не виртуальные методы, которые «одобряются» для частных виртуальных методов:
источник
Как насчет аналогии: когда я был в ВВС, я прошел подготовку пилотов и стал пилотом ВВС США (ВВС США). В тот момент я не был квалифицирован, чтобы летать на чем-либо, и должен был посещать обучение по типу самолета. После того, как я получил квалификацию, я был пилотом (абстрактный класс) и пилотом C-141 (конкретный класс). На одном из моих заданий мне дали дополнительную обязанность: офицер безопасности. Теперь я был еще пилотом и пилотом C-141, но я также выполнял обязанности сотрудника по безопасности (я, так сказать, реализовал ISafetyOfficer). Пилот не должен был быть офицером безопасности, другие люди тоже могли это сделать.
Все пилоты ВВС США должны следовать определенным правилам военно-воздушных сил, а все пилоты C-141 (или F-16, или T-38) являются «пилотами ВВС США». Любой может быть офицером безопасности. Итак, подведем итог:
добавленное примечание: это должна была быть аналогия, помогающая объяснить концепцию, а не рекомендация по кодированию. Смотрите различные комментарии ниже, обсуждение интересно.
источник
Jay
не может наследоваться от нескольких классов (пилот C-141, пилот F-16 и пилот T-38), означает ли это, что чьи классы должны стать интерфейсами? СпасибоЯ думаю, что ответ, который они ищут, - это принципиальное различие или философское отличие OPPS.
Наследование абстрактного класса используется, когда производный класс разделяет основные свойства и поведение абстрактного класса. Тип поведения, который на самом деле определяет класс.
С другой стороны, наследование интерфейса используется, когда классы имеют периферийное поведение, которое не обязательно определяет производный класс.
Например, Автомобиль и Грузовик имеют много основных свойств и поведения абстрактного класса Automobile, но они также имеют некоторое периферийное поведение, такое как Генерация выхлопных газов, которое разделяют даже не автомобильные классы, такие как Drillers или PowerGenerators, и не обязательно определяют Автомобиль или Грузовик. Таким образом, Car, Truck, Driller и PowerGenerator могут использовать один и тот же интерфейс IExhaust.
источник
accelerate
является частью основного поведения автомобильного абстрактного класса, то я не могу сказать, чтоaccelerate
показывает характер контракта . что такое контрактный характер? почему это словоcontract
вводится всякий раз, когда мы говоримinterface
?interface
необходимо иметь периферийное поведение, то почемуpublic interface List<E> extends Collection<E> {}
он предназначен для описания основного поведенияlist
? это на самом деле противоречит ответу прасуна. ОбаCollection<E>
иList<E>
здесь интерфейсы.Коротко: Абстрактные классы используются для моделирования иерархии классов похожих классов (например, Animal может быть абстрактным классом, а Human, Lion, Tiger могут быть конкретными производными классами)
А ТАКЖЕ
Интерфейс используется для связи между 2 подобными / не похожими классами, которые не заботятся о типе класса, реализующего интерфейс (например, Высота может быть свойством интерфейса и может быть реализована человеком, зданием, деревом. Неважно, можете ли вы есть , вы можете плавать, вы можете умереть или что-нибудь еще ... это имеет значение только то, что вам нужно иметь высоту (реализация в вашем классе)).
источник
Есть несколько других отличий -
Интерфейсы не могут иметь никаких конкретных реализаций. Абстрактные базовые классы могут. Это позволяет вам предоставлять конкретные реализации там. Это может позволить абстрактному базовому классу фактически предоставить более строгий контракт, тогда как интерфейс действительно только описывает, как используется класс. (Абстрактный базовый класс может иметь не виртуальные члены, определяющие поведение, что дает больше контроля автору базового класса.)
В одном классе может быть реализовано более одного интерфейса. Класс может быть производным только от одного абстрактного базового класса. Это допускает полиморфную иерархию с использованием интерфейсов, но не абстрактных базовых классов. Это также учитывает псевдо-мульти-наследование с использованием интерфейсов.
Абстрактные базовые классы могут быть изменены в v2 + без нарушения API. Изменения в интерфейсах разрушают изменения.
[C # /. NET Specific] Интерфейсы, в отличие от абстрактных базовых классов, могут применяться к типам значений (структурам). Структуры не могут наследоваться от абстрактных базовых классов. Это позволяет применять поведенческие контракты / рекомендации по использованию к типам значений.
источник
Наследование
Рассмотрим машину и автобус. Это два разных автомобиля. Но, тем не менее, они имеют некоторые общие свойства, такие как рулевое управление, тормоза, шестерни, двигатель и т. Д.
Так что с концепцией наследования это можно представить следующим образом ...
Теперь велосипед ...
И автомобиль ...
Это все о наследовании . Мы используем их для классификации объектов на более простые формы Base и их потомков, как мы видели выше.
Абстрактные классы
Абстрактные классы являются неполными объектами. Чтобы понять это далее, давайте еще раз рассмотрим аналогию с автомобилем.
Транспортное средство можно вести. Правильно? Но разные транспортные средства управляются по-разному ... Например, вы не можете водить машину так же, как водите велосипед.
Итак, как представить функцию движения транспортного средства? Труднее проверить, что это за тип транспортного средства, и управлять им со своей функцией; вам придется менять класс водителя снова и снова при добавлении нового типа транспортного средства.
Здесь идет роль абстрактных классов и методов. Вы можете определить метод drive как абстрактный, чтобы сказать, что каждый наследующий потомок должен реализовать эту функцию.
Так что, если вы измените класс автомобиля ...
Велосипед и Автомобиль также должны указать, как им управлять. В противном случае код не скомпилируется и выдается ошибка.
Вкратце ... абстрактный класс - это частично неполный класс с некоторыми незавершенными функциями, которые наследующие потомки должны указывать свои собственные.
Интерфейсы Интерфейсы полностью неполные. У них нет никаких свойств. Они просто указывают на то, что наследующие дети способны что-то делать ...
Предположим, у вас есть разные типы мобильных телефонов. У каждого из них есть разные способы выполнять разные функции; Пример: позвонить человеку. Производитель телефона указывает, как это сделать. Здесь мобильные телефоны могут набирать номер, то есть он может набирать номер. Давайте представим это как интерфейс.
Здесь создатель Dialable определяет, как набрать номер. Вам просто нужно дать ему номер для набора.
Таким образом, используя интерфейсы вместо абстрактных классов, разработчику функции, которая использует Dialable, не нужно беспокоиться о его свойствах. Пример: есть ли у него сенсорный экран или клавиатура, стационарный телефон или мобильный телефон. Вам просто нужно знать, можно ли набрать номер; наследует ли (или реализует) интерфейс Dialable.
И что еще более важно , если когда-нибудь вы переключите Dialable с другим
Вы можете быть уверены, что код по-прежнему работает отлично, потому что функция, которая использует набор номера, не зависит (и не может) зависеть от деталей, отличных от указанных в интерфейсе набора номера. Они оба реализуют интерфейс Dialable, и это единственное, о чем заботится функция.
Разработчики обычно используют интерфейсы для обеспечения взаимодействия (взаимозаменяемости) между объектами, поскольку они имеют общую функцию (точно так же, как вы можете перейти на стационарный или мобильный телефон, если вам просто нужно набрать номер). Короче говоря, интерфейсы - это гораздо более простая версия абстрактных классов без каких-либо свойств.
Также обратите внимание, что вы можете реализовать (наследовать) столько интерфейсов, сколько захотите, но вы можете расширять (наследовать) только один родительский класс.
Больше информации Абстрактные классы и интерфейсы
источник
Если вы считаете
java
язык ООП для ответа на этот вопрос, выпуск Java 8 приводит к тому, что часть содержимого в ответах выше устарела. Теперь интерфейс Java может иметь методы по умолчанию с конкретной реализацией.Oracle сайт предоставляет основные различия между
interface
иabstract
классом.Рассмотрите возможность использования абстрактных классов, если:
Рассмотрите возможность использования интерфейсов, если:
Serializable
интерфейс.Проще говоря, я хотел бы использовать
интерфейс: для реализации контракта несколькими несвязанными объектами
абстрактный класс: для реализации одинакового или разного поведения среди нескольких связанных объектов
Взгляните на пример кода, чтобы ясно понять вещи: как мне объяснить разницу между интерфейсом и классом Abstract?
источник
Интервьюеры лают странное дерево. Для языков, таких как C # и Java, есть разница, но в других языках, таких как C ++, нет. Теория ОО не различает их, а только синтаксис языка.
Абстрактный класс - это класс с реализацией и интерфейсом (чисто виртуальные методы), которые будут наследоваться. Интерфейсы обычно не имеют никакой реализации, а только чисто виртуальные функции.
В C # или Java абстрактный класс без какой-либо реализации отличается от интерфейса только синтаксисом, используемым для его наследования, и тем фактом, что вы можете наследовать только от одного.
источник
Реализуя интерфейсы, вы получаете композицию (отношения «есть») вместо наследования (отношения «есть»). Это важный принцип, который нужно помнить, когда дело доходит до таких вещей, как шаблоны проектирования, когда вам нужно использовать интерфейсы для достижения композиции поведения вместо наследования.
источник
Я объясню детали глубины интерфейса и абстрактного класса. Если вы знаете обзор интерфейса и абстрактного класса, то сначала у вас возникнет вопрос, когда нам следует использовать интерфейс и когда мы должны использовать абстрактный класс. Поэтому, пожалуйста, проверьте ниже объяснение интерфейса и абстрактного класса.
Когда мы должны использовать интерфейс?
если вы не знаете о реализации, просто у нас есть спецификация требований, то мы идем с интерфейсом
Когда мы должны использовать абстрактный класс?
если вы знаете реализацию, но не полностью (частично реализацию), тогда мы идем с классом Abstract.
Интерфейс
каждый метод по умолчанию открытый интерфейс означает, что интерфейс на 100% чистый.
Аннотация
может иметь конкретный метод и абстрактный метод, то есть метод Бетон, который имеет реализацию в абстрактном классе. Абстрактный класс - это класс, который объявлен абстрактным - он может включать или не включать абстрактные методы.
Интерфейс
Мы не можем объявить интерфейс как частный, защищенный
В. Почему мы не объявляем интерфейс закрытым и защищенным?
Потому что по умолчанию метод интерфейса является публичным абстрактным, поэтому мы не объявляем интерфейс закрытым и защищенным.
Метод интерфейса
также мы не можем объявить интерфейс как частный, защищенный, окончательный, статический, синхронизированный, родной .....
Я приведу причину: почему мы не объявляем синхронизированный метод, потому что мы не можем создать объект интерфейса и синхронизировать, это работа над объектом, и причина того, что мы не объявляем синхронизированный метод, концепция переходных процессов также не применима, потому что временная работа с синхронизированными.
Аннотация
мы с удовольствием используем публичную, приватную финальную статическую .... означает, что никакие ограничения не применяются в абстрактном виде.
Интерфейс
Переменные объявляются в интерфейсе как открытый статический финал по умолчанию, поэтому мы также не объявляем переменную как частную защищенную.
Модификатор volatile также не применяется в интерфейсе, поскольку переменная интерфейса по умолчанию является общедоступной статической конечной и конечной переменными. Вы не можете изменить значение, если оно присвоит значение переменной, а после объявления переменной в интерфейсе необходимо назначить переменную.
И изменчивая переменная это держать изменения, так что это опп. в конечном итоге это причина того, что мы не используем переменную volatile в интерфейсе.
Аннотация
Абстрактная переменная не нуждается в объявлении public static final.
Я надеюсь, что эта статья полезна.
источник
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С концептуальной точки зрения, сохранение реализации, правил, преимуществ и достижения любой цели программирования с использованием кого-либо или обоих, может или не может иметь код / данные / свойство, бла-бла, одиночное или множественное наследование, все в стороне
1- Абстрактный (или чистый абстрактный) класс предназначен для реализации иерархии. Если ваши бизнес-объекты выглядят несколько структурно схожими, представляя только родительско-дочерние (иерархические) отношения, тогда будут использоваться классы наследования / абстрактные. Если ваша бизнес-модель не имеет иерархии, тогда не следует использовать наследование (здесь я не говорю о логике программирования, например, некоторые шаблоны проектирования требуют наследования). Концептуально абстрактный класс - это метод реализации иерархии бизнес-модели в ООП, он не имеет ничего общего с интерфейсами, фактически сравнивать абстрактный класс с интерфейсом бессмысленно, поскольку оба концептуально совершенно разные вещи, в интервью его просят просто проверить концепции, потому что, похоже, оба обеспечивают несколько одинаковую функциональность, когда речь идет о реализации, и мы, программисты, обычно уделяем больше внимания кодированию. Помните также, что абстракция отличается от абстрактного класса.
2- Интерфейс - это контракт, полная бизнес-функциональность, представленная одним или несколькими наборами функций. Вот почему он реализован, а не наследуется. Бизнес-объект (часть иерархии или нет) может иметь любое количество полных бизнес-функций. Это не имеет ничего общего с абстрактными классами, означает наследование в целом. Например, человек может запустить, слон может выполнить, птица может выполнить и т.д., все эти объекты различной иерархии будут реализовывать интерфейс RUN или интерфейс EAT или SPEAK. Не входите в реализацию, поскольку вы можете реализовать ее как наличие абстрактных классов для каждого типа, реализующего эти интерфейсы. Объект любой иерархии может иметь функциональность (интерфейс), которая не имеет ничего общего с его иерархией.
Я считаю, что интерфейсы не были изобретены для достижения множественного наследования или для демонстрации открытого поведения, и аналогично, чистые абстрактные классы не должны отменять интерфейсы, но интерфейс - это функциональность, которую может выполнять объект (через функции этого интерфейса), а абстрактный класс представляет родительский элемент иерархии для создания дочерних элементов, имеющих базовую структуру (свойство + функциональность) родительского элемента
Когда вас спрашивают о разнице, это на самом деле концептуальная разница, а не разница в реализации, зависящей от языка, если это не задано явно.
Я полагаю, что оба интервьюера ожидали однозначного различия между этими двумя, а когда вы потерпели неудачу, они пытались подтолкнуть вас к этому различию, внедрив ОДНОГО как ДРУГОЕ
источник
Для .Net,
Ваш ответ Второму интервьюеру - также ответ на первый ... Абстрактные классы могут иметь реализацию, И состояние, интерфейсы не могут ...
РЕДАКТИРОВАТЬ: С другой стороны, я бы даже не использовал фразу «подкласс» (или фразу «наследование») для описания классов, которые «определены для реализации» интерфейса. Для меня интерфейс - это определение контракта, которому должен соответствовать класс, если он был определен для «реализации» этого интерфейса. Он ничего не наследует ... Вы должны сами все добавить, явно.
источник
Интерфейс : следует использовать, если вы хотите наложить правило на компоненты, которые могут или не могут быть связаны друг с другом
Плюсы:
Минусы:
Абстрактный класс : должен использоваться там, где вы хотите иметь базовое или стандартное поведение или реализацию для компонентов, связанных друг с другом
Плюсы:
Минусы:
источник
Я думаю, что им не понравился ваш ответ, потому что вы дали технические отличия вместо конструктивных. Вопрос для меня как вопрос тролля. На самом деле интерфейсы и абстрактные классы имеют совершенно другую природу, поэтому вы не можете их реально сравнить. Я дам вам свое видение роли интерфейса и роли абстрактного класса.
Интерфейс: используется для обеспечения контракта и создания слабой связи между классами, чтобы иметь более поддерживаемое, масштабируемое и тестируемое приложение.
абстрактный класс: используется только для разложения некоторого кода между классами с одинаковой ответственностью. Обратите внимание, что это является основной причиной, по которой множественное наследование является плохой вещью в ООП, поскольку класс не должен обрабатывать многие обязанности ( вместо этого используйте композицию ).
Таким образом, интерфейсы играют реальную архитектурную роль, в то время как абстрактные классы являются почти только частью реализации (если вы, конечно, используете их правильно).
источник
В документах четко сказано, что если абстрактный класс содержит только объявления абстрактных методов, он должен быть объявлен как интерфейс.
Переменные в интерфейсах по умолчанию являются общедоступными static и final. Вопрос может быть сформулирован так, как если бы все переменные в абстрактном классе были публичными? Ну, они все еще могут быть не статичными и не финальными в отличие от переменных в интерфейсах.
Наконец, я хотел бы добавить еще один момент к упомянутым выше - абстрактные классы все еще являются классами и попадают в одно дерево наследования, тогда как интерфейсы могут присутствовать в множественном наследовании.
источник
Это мое мнение.
источник
Скопировано из 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. Предоставляя базовый тип с хорошей реализацией по умолчанию, вы начинаете с использования типа, который работает и хорошо протестирован; затем вы можете изменить детали, которые нуждаются в модификации.
■■ Управление версиями Если вы добавляете метод к базовому типу, производный тип наследует новый метод, вы начинаете с использования работающего типа, и исходный код пользователя даже не нужно перекомпилировать. Добавление нового члена в интерфейс заставляет наследника интерфейса изменить его исходный код и перекомпилировать.
источник
abstract class
.Интерфейс определяет контракт на услугу или набор услуг. Они обеспечивают полиморфизм по горизонтали в том смысле, что два совершенно не связанных между собой класса могут реализовывать один и тот же интерфейс, но использоваться взаимозаменяемо в качестве параметра типа интерфейса, который они реализуют, поскольку оба класса обещают удовлетворить набор услуг, определенный интерфейсом. Интерфейсы не предоставляют подробности реализации.
Абстрактный класс определяет базовую структуру для своих подклассов и, возможно, частичную реализацию. Абстрактные классы обеспечивают полиморфизм вертикальным, но направленным образом, так что любой класс, который наследует абстрактный класс, может рассматриваться как экземпляр этого абстрактного класса, но не наоборот. Абстрактные классы могут и часто содержат детали реализации, но не могут быть созданы сами по себе - только их подклассы могут быть «обновлены».
Заметьте, C # также допускает наследование интерфейса.
источник
В большинстве ответов основное внимание уделяется техническому различию между абстрактным классом и интерфейсом, но, поскольку технически интерфейс по сути является своего рода абстрактным классом (класс без каких-либо данных или реализации), я думаю, что концептуальное различие гораздо интереснее, и это может быть интервьюеры после.
Интерфейс представляет собой соглашение . В нем указано: «так мы будем разговаривать друг с другом». Он не может иметь никакой реализации, потому что он не должен иметь никакой реализации. Это контракт. Это как
.h
заголовочные файлы в C.Абстрактный класс является неполной реализацией . Класс может реализовывать или не реализовывать интерфейс, а абстрактный класс не должен реализовывать его полностью. Абстрактный класс без какой-либо реализации бесполезен, но абсолютно легален.
По сути, любой класс, абстрактный или нет, - это то, чем он является , а интерфейс - как вы его используете . Например:
Animal
может быть абстрактный класс, реализующий некоторые основные метаболические функции и задающий абстрактные методы для дыхания и передвижения, не давая реализации, потому что он не знает, должен ли он дышать через жабры или легкие, и летает ли он, плавает, гуляет или ползает.Mount
с другой стороны, это может быть интерфейс, который указывает, что вы можете ездить на животном, не зная, какое это животное (или вообще это животное!).Тот факт, что за кулисами интерфейс является в основном абстрактным классом с использованием только абстрактных методов, не имеет значения. Концептуально они исполняют совершенно разные роли.
источник
Поскольку вы, возможно, получили теоретические знания от экспертов, я не буду тратить много слов, чтобы повторить все это здесь, а позвольте мне объяснить на простом примере, где мы можем использовать / не можем использовать
Interface
иAbstract class
.Предположим, вы разрабатываете приложение, чтобы перечислить все функции автомобилей. В разных точках вам нужно общее наследование, так как некоторые свойства, такие как DigitalFuelMeter, кондиционер, регулировка сиденья и т. Д., Являются общими для всех автомобилей. Аналогично, нам нужно наследование только для некоторых классов, поскольку некоторые свойства, такие как тормозная система (ABS, EBD), применимы только для некоторых автомобилей.
Приведенный ниже класс выступает в качестве базового класса для всех автомобилей:
Представьте, что у нас есть отдельный класс для каждой машины.
Предположим, нам нужен метод наследования технологии торможения для автомобилей Verna и Cruze (неприменимо для Alto). Хотя оба используют технологию торможения, «технология» отличается. Итак, мы создаем абстрактный класс, в котором метод будет объявлен как Abstract, и он должен быть реализован в его дочерних классах.
Сейчас мы пытаемся унаследовать от этого абстрактного класса, и тип системы торможения реализован в Verna и Cruze:
Видите проблему в двух вышеупомянутых классах? Они наследуются от нескольких классов, которые C # .Net не позволяет, хотя метод реализован в дочерних элементах. Здесь приходит необходимость интерфейса.
И реализация приведена ниже:
Теперь Verna и Cruze могут добиться множественного наследования с помощью собственных технологий торможения с помощью интерфейса.
источник
Интерфейсы - это легкий способ реализации определенного поведения. Это один из способов думать.
источник
Эти ответы слишком длинные.
Интерфейсы предназначены для определения поведения.
Абстрактные классы предназначены для определения самой вещи, включая ее поведение. Вот почему мы иногда создаем абстрактный класс с некоторыми дополнительными свойствами, наследующими интерфейс.
Это также объясняет, почему Java поддерживает единственное наследование классов, но не ограничивает интерфейсы. Потому что конкретный объект не может быть разными вещами, но может иметь разное поведение.
источник
1) Интерфейс можно рассматривать как чистый абстрактный класс, он такой же, но, несмотря на это, не то же самое для реализации интерфейса и наследования от абстрактного класса. Когда вы наследуете от этого чистого абстрактного класса, вы определяете иерархию -> наследование, если вы реализуете интерфейс, которым вы не являетесь, и вы можете реализовать столько интерфейсов, сколько хотите, но вы можете наследовать только от одного класса.
2) Вы можете определить свойство в интерфейсе, поэтому класс, реализующий этот интерфейс, должен иметь это свойство.
Например:
Класс, реализующий этот интерфейс, должен иметь такое свойство.
источник
Хотя этот вопрос довольно старый, я хотел бы добавить еще один момент в пользу интерфейсов:
Интерфейсы могут быть внедрены с использованием любых инструментов Dependency Injection, тогда как внедрение класса Abstract поддерживается очень немногими.
источник
Из другого моего ответа , в основном касающегося того, когда использовать один против другого:
источник
Типы интерфейса и абстрактные базовые классы
Адаптировано из Pro C # 5.0 и книги .NET 4.5 Framework .
Тип интерфейса может показаться очень похожим на абстрактный базовый класс. Напомним, что когда класс помечен как абстрактный, он может определять любое количество абстрактных членов, чтобы обеспечить полиморфный интерфейс для всех производных типов. Однако даже когда класс определяет набор абстрактных членов, он также может свободно определять любое количество конструкторов, полевых данных, неабстрактных членов (с реализацией) и так далее. Интерфейсы, с другой стороны, содержат только абстрактные определения членов. Полиморфный интерфейс, созданный абстрактным родительским классом, страдает одним серьезным ограничением в том, что только производные типы поддерживают члены, определенные абстрактным родительским классом. Однако в более крупных программных системах очень часто разрабатываются множественные иерархии классов, у которых нет общего родителя, кроме System.Object. Учитывая, что абстрактные члены в абстрактном базовом классе применяются только к производным типам, у нас нет способа настроить типы в разных иерархиях для поддержки одного и того же полиморфного интерфейса. В качестве примера предположим, что вы определили следующий абстрактный класс:
Учитывая это определение, только члены, расширяющие CloneableType, могут поддерживать метод Clone (). Если вы создадите новый набор классов, которые не расширяют этот базовый класс, вы не сможете получить этот полиморфный интерфейс. Также вы можете вспомнить, что C # не поддерживает множественное наследование классов. Поэтому, если вы хотите создать MiniVan, который является автомобилем и является CloneableType, вы не можете сделать это:
Как вы могли догадаться, на помощь приходят типы интерфейсов. После того, как интерфейс был определен, он может быть реализован любым классом или структурой, в любой иерархии, в любом пространстве имен или любой сборке (написанной на любом языке программирования .NET). Как видите, интерфейсы очень полиморфны. Рассмотрим стандартный интерфейс .NET с именем ICloneable, определенный в пространстве имен System. Этот интерфейс определяет один метод с именем Clone ():
источник
Ответ на второй вопрос:
public
переменная, определенная вinterface
,static final
по умолчанию, тогда какpublic
переменная вabstract
классе является переменной экземпляра.источник
Конечно, важно понимать поведение интерфейса и абстрактного класса в ООП (и как языки обрабатывают их), но я думаю, что также важно понимать, что именно означает каждый термин. Можете ли вы представить, что
if
команда не работает точно как значение термина? Кроме того, на самом деле некоторые языки сокращают, даже больше, различия между интерфейсом и абстрактным ... если случайно однажды два термина работают почти одинаково, по крайней мере, вы можете сами определить, где (и почему) должен быть любой из них. используется для.Если вы читаете некоторые словари и другие шрифты, вы можете найти разные значения для одного и того же термина, но с некоторыми общими определениями. Я думаю, что эти два значения, которые я нашел на этом сайте , действительно, действительно хороши и подходят.
Интерфейс:
Аннотация:
Пример:
Вы купили машину, и ей нужно топливо.
Модель вашего автомобиля -
XYZ
жанроваяABC
, то есть это конкретный автомобиль, конкретный экземпляр автомобиля. Автомобиль не настоящий объект. Фактически это абстрактный набор стандартов (качеств) для создания конкретного объекта. Короче говоря, Car - это абстрактный класс , это «то, что концентрирует в себе основные качества чего-то более обширного или более общего» .Единственное топливо, которое соответствует спецификации автомобиля, должно использоваться для заполнения бака автомобиля. На самом деле, ничто не может ограничить вас заправкой любого топлива, но двигатель будет работать правильно только с указанным топливом, поэтому лучше следовать его требованиям. Требования говорят, что он принимает, как и другие автомобили того же жанра
ABC
, стандартный набор топлива.В объектно-ориентированном представлении топливо для жанра
ABC
не должно быть объявлено как класс, потому что нет никакого конкретного топлива для определенного жанра автомобиля. Несмотря на то, что ваш автомобиль может принимать абстрактный класс «Fuel» или «AutularFuel», вы должны помнить, что только некоторые из существующих автомобильных топлив соответствуют техническим требованиям, которые соответствуют требованиям, изложенным в руководстве по эксплуатации вашего автомобиля. Короче говоря, они должны реализовать интерфейсABCGenreFuel
, который «... позволяет отдельным и иногда несовместимым элементам эффективно координировать» .добавление
Кроме того, я думаю, вы должны иметь в виду значение термина «класс», который (с того же сайта, о котором упоминалось ранее):
Учебный класс:
Таким образом, класс (или абстрактный класс) должен представлять не только общие атрибуты (например, интерфейс), но и какую-то группу с общими атрибутами. Интерфейс не должен представлять вид. Он должен представлять общие атрибуты. Таким образом, я думаю, что классы и абстрактные классы могут использоваться для представления вещей, которые не должны часто менять свои аспекты, например, человек, являющийся млекопитающим, потому что он представляет некоторые виды. Виды не должны менять себя так часто.
источник
С точки зрения кодирования
Интерфейс может заменить Абстрактный класс, если Абстрактный класс имеет только абстрактные методы. В противном случае изменение класса Abstract на интерфейс означает, что вы потеряете возможность повторного использования кода, которую обеспечивает Inheritance.
С точки зрения дизайна
Сохраняйте его как абстрактный класс, если это отношение «является», и вам нужен поднабор или все функции. Сохраняйте его как интерфейс, если это отношения «следует делать».
Решите, что вам нужно: только применение политики или повторное использование кода и политика.
источник
Пара других отличий:
Абстрактные классы могут иметь статические методы, свойства, поля и т. Д. И операторы, интерфейсы не могут. Оператор приведения допускает приведение к / из абстрактного класса, но не разрешает приведение к / из интерфейса.
Так что в значительной степени вы можете использовать абстрактный класс сам по себе, даже если он никогда не реализован (через его статические члены), и вы не можете использовать интерфейс самостоятельно.
источник