Интерфейс против абстрактного класса (общий ОО) - PullRequest
1329 голосов
/ 17 апреля 2009

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

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

Интерфейс:

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

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

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

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

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

См. Также :

Ответы [ 34 ]

9 голосов
/ 19 января 2010

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

6 голосов
/ 05 октября 2009

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

6 голосов
/ 26 августа 2012

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

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

6 голосов
/ 17 апреля 2009

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

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

Например:

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

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

6 голосов
/ 30 августа 2014

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

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

Тип интерфейса может показаться очень похожим на абстрактный базовый класс. Отзыв что когда класс помечен как абстрактный, он может определить любое количество абстрактных членов для полиморфный интерфейс для всех производных типов. Тем не менее, даже когда класс определяет набор абстрактных члены, также можно свободно определять любое количество конструкторов, полевых данных, неабстрактных членов (с реализация) и так далее. Интерфейсы, с другой стороны, содержат только абстрактные определения членов. Полиморфный интерфейс, установленный абстрактным родительским классом, страдает одним существенным ограничением в том, что только производные типы поддерживают члены, определенные абстрактным родителем. Однако в большем В программных системах очень распространено создание нескольких иерархий классов, у которых нет общего родителя. за пределы 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();
}
5 голосов
/ 17 апреля 2009

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

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

4 голосов
/ 05 января 2016

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

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

Интерфейс:

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

Аннотация:

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

Пример:

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

enter image description here

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

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

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

Добавление

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

Класс:

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

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

4 голосов
/ 21 февраля 2014

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

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

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

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

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

3 голосов
/ 13 мая 2010

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

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

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

3 голосов
/ 12 сентября 2013

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

Примером в режиме реального времени может быть любой 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
    ....
    ....
}

Здесь Fastrack называется часами, потому что 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. Реализация класса завершит эту реализацию.

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

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

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

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