Почему делают обоих, которые абстрактный класс и интерфейс существуют в C#?

dict(map( lambda a:[a[1],a[0]], d.iteritems() ))
13
задан nawfal 7 July 2014 в 09:54
поделиться

10 ответов

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

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

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

РЕДАКТИРОВАТЬ: Так же, как наиболее удобный способ опровергнуть третий пункт Ибушкина в его комментарии ... вы можете переопределить абстрактный метод с помощью не виртуальный (с точки зрения невозможности его дальнейшего переопределения), запечатав его:

public abstract class AbstractBase
{
    public abstract void Foo();
}

public class Derived : AbstractBase
{
    public sealed override void Foo() {}
}

Классы, производные от Производные , не могут больше переопределить Foo .

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

29
ответ дан 1 December 2019 в 17:26
поделиться

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

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

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

8
ответ дан 1 December 2019 в 17:26
поделиться

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

Например, предположим, что я создаю класс, подобный Car, и я подклассифицирую три подкласса: RearWheelDrive, FrontWheelDrive и AllWheelDrive. Теперь я решил, что мне нужно разрезать классы по другой «оси», как с кнопочным пускателем, так и без него. Я хочу, чтобы все автомобили с кнопочным запуском имели метод "PushStartButton ()", а автомобили без кнопок - метод TurnKey (), и я хочу иметь возможность обрабатывать объекты Car (в отношении их запуска) независимо от того, какой подкласс они есть. Я могу определять интерфейсы, которые могут реализовать мои классы, такие как IPushButtonStart и IKeyedIgnition, поэтому у меня есть общий способ работы с моими объектами, которые отличаются способом, не зависящим от единственного базового класса, от которого каждый является производным.

2
ответ дан 1 December 2019 в 17:26
поделиться

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

Вы можете видеть это как - это , а реализует .
т.е. Учетная запись может быть абстрактной базовой учетной записью, потому что у вас может быть CheckingAccount , SavingsAccount и т. Д., Которые являются производными от абстрактного базового класса Account ]. Абстрактные базовые классы могут также содержать не абстрактные методы, свойства и поля, как и любой нормальный класс. Однако только интерфейсы содержат абстрактные методы и свойства, которые должны быть реализованы.

C # позволяет наследовать только один базовый класс - одинарное наследование, как и java. Однако вы можете реализовать столько интерфейсов, сколько захотите - это потому, что интерфейс - это просто контракт, который ваш класс обещает реализовать.

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

16
ответ дан 1 December 2019 в 17:26
поделиться

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

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

1
ответ дан 1 December 2019 в 17:26
поделиться

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

1
ответ дан 1 December 2019 в 17:26
поделиться

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

0
ответ дан 1 December 2019 в 17:26
поделиться

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

0
ответ дан 1 December 2019 в 17:26
поделиться

Они служат двум совершенно разным целям.

Абстрактные классы обеспечивают способ наследования объекта от определенного контракта, а также позволяют определять поведение в базовом классе. Это, с теоретической точки зрения, обеспечивает связь IS-A в том смысле, что конкретный класс IS-A является конкретным типом базового класса.

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

0
ответ дан 1 December 2019 в 17:26
поделиться

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

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

Если метод принимает интерфейс IEnumerable в качестве параметра, это означает, что его интересует только возможность итерации по членам. Вы можете использовать несколько разных классов с этой возможностью (например, List

0
ответ дан 1 December 2019 в 17:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: