Какая разница между абстрактным классом и интерфейсом?
Предположим, что в интерфейсе мы имеем два метода M1()
и M2()
. В абстрактном классе также есть те же два абстрактных метода. Если какой-либо класс реализовал этот интерфейс или унаследовал от абстрактного класса, ему придется реализовать оба метода в нем.
Итак, мне кажется, что интерфейс или абстрактный класс ведут себя одинаково для моего сценария. Итак, может ли кто-нибудь выделить разницу между этими двумя в этом конкретном случае и предложить ли использовать абстрактный класс или интерфейс здесь?
Ответы
Ответ 1
Между абстрактными классами и интерфейсами существуют технические различия, заключающиеся в том, что будучи абстрактным классом, он может содержать реализацию методов, полей, конструкторов и т.д., В то время как интерфейс содержит только прототипы методов и свойств. Класс может реализовывать несколько интерфейсов, но он может наследовать только один класс (абстрактный или другой).
Однако, на мой взгляд, самое важное различие между интерфейсами и абстрактными классами - это семантическая разница.
Интерфейс определяет, что что-то может делать (как оно ведет себя), а абстрактный класс определяет, что что-то.
Возьмем, к примеру, IEnumerable
, семантическое значение этого состоит в том, что все, что реализует IEnumerable
является перечислимым, это не означает, что это перечисление, но что оно может вести себя как единое целое (может быть перечислено).
Сравните с примером стиральной машины, все, что наследует это тип стиральной машины. Все, что наследуется, будет стиральной машиной, верхним или боковым погрузчиком и т.д.
Вместо этого, если у вас есть интерфейс с именем ICanWash
, который может содержать метод с именем Wash
. У вас могут быть разные вещи, реализующие ICanWash
, будь то Person
, абстрактный класс стиральной машины и т.д., Где фактическая реализация не имеет значения, просто вам нужно знать, что поведение может стирать вещи.
Таким образом, классы определяют, что что-то есть, интерфейсы определяют, что что-то может делать.
Ответ 2
Из MSDN:
Используя интерфейсы, вы можете, например, включить поведение из несколько источников в классе. Эта возможность важна в С# , потому что язык не поддерживает множественное наследование классов
Итак, используйте интерфейс, если вы хотите, чтобы любой класс мог наследовать эти методы.
С той же страницы MSDN:
Кроме того, вы должны использовать интерфейс, если хотите имитировать наследования для структур, поскольку они фактически не могут наследовать другой структуры или класса.
Ответ 3
Интерфейс позволяет классу наследовать/реализовывать более одного интерфейса, тогда как в С# вы можете наследовать только один класс.
Множественное наследование, в основном.
Ответ 4
Абстрактный класс не только содержит абстрактные методы, но также может содержать другие поля и методы с реализацией. В С# вы не можете наследовать из многоуровневых классов, но вы можете реализовать мультиплексированные интерфейсы. Итак, короткий ответ:
по возможности используйте интерфейсы, а не абстрактные классы.
В вашем примере это возможно и рекомендуется использовать интерфейс.
Ответ 5
Две быстрые мысли о различиях между интерфейсами и абстрактными классами:
- Абстрактные классы желательны, если будущее расширение, скорее всего,
абстрактный класс может быть расширен, но интерфейс должен быть
с добавлением другого интерфейса, I2.
- Одиночный (реализация) метод наследования выбирает абстрактные классы
careully, чтобы наиболее точно отразить истинную основную природу. Интерфейсы
можно легко добавить к выполнению, но абстрактный класс может
добавляется только в том случае, если его уже нет.