2009-10-25 3 views
4

Что необходимо для интерфейсов в C#? поскольку мы пишем абстрактный метод в интерфейсах. вместо этого мы можем напрямую реализовать эти методы в классе.Необходимость интерфейсов в C#

+2

Извините, что именно вы спрашиваете? Как использовать интерфейс? – GenericTypeTea

+1

Что такое интерфейс? вы можете напрямую писать метод в классе –

+1

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

ответ

2

Возможно, вы захотите ознакомиться с polymorphism.

+1

Википедия а? ;-) Возможно, эта ссылка также полезна (и более конкретно): http://msdn.microsoft.com/en-us/library/ms173156.aspx – RedGlyph

7

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

+1

+1. Для кого-то * наконец * указывая: * интерфейсы не ограничены иерархиями * – 2009-10-25 22:08:02

4

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

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

+3

Как насчет модульного тестирования? Обычно я использую интерфейсы, потому что я создаю вторую реализацию как заглушку или макет для тестирования. Создание вашего правила означает, что вы всегда должны использовать интерфейсы. – 2009-10-25 13:05:29

+2

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

+3

@DotNetWill и Брайан Генисио: Я не понимаю, как то, что вы написали, никак не противоречит тому, что я написал в своем ответе. Если вы решили издеваться над классом для модульного тестирования, тогда у вас будет более одного класса, который реализует интерфейс, и вам, таким образом, необходимо использовать интерфейс. Если вы не издеваетесь/не заглушаете класс для модульного тестирования, и у вас есть только одна реализация этого класса в вашем проекте, тогда вам не нужен интерфейс. Я что-то пропустил в ваших комментариях? Вы говорите, что * каждый класс * в * каждом проекте * должен реализовывать интерфейс? Это кажется чрезмерно сильным утверждением. – MusiGenesis

1

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

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

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

0

Подумайте о интерфейсах как контрактах.

Вы создаете контракт, которым должен следовать класс. Например, если наш объект Dog должен иметь метод Walk, он определяет класс , должен реализовать этот метод.

Чтобы заставить каждый класс собаки (унаследованный или нет) реализовать этот метод, вы должны заставить их присоединиться к контракту. I. Назначить интерфейс, который определяет этот метод.

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

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

+0

@Gary, но абстрактный класс также является контрактом :) – 2009-10-25 22:07:07

+0

Правда, но это не влияет на мой ответ. –

1

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

Например:

1) попробовать, без интерфейса, чтобы выставить некоторую часть функциональности, реализованной в сборке «A», чтобы сборки «B», без фактической реализации, видимой сборки «A».

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

0

Если вы хотите написать тестируемый код, вам обычно потребуется использовать интерфейсы. При тестировании модулей вы можете иметь ClassA, который зависит от ClassB, который зависит от ClassC и т. Д., Но вы хотите протестировать ClassA. Вы, конечно же, не хотите создавать ClassC для перехода к ClassB только для создания класса ClassA.

В этом случае вы делаете ClassA зависимым от IClassB (или более общего имени, скорее всего, не подразумевая ничего о реализации ClassB) и издеваетесь над IClassB в ваших тестах.

Это все для управления зависимостями для меня.

0

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

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

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

0

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

0

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

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

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

0

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

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

0

Как представлено GoF 1-й принцип: Программа для интерфейса не является реализацией.

Это помогает во многих отношениях. Легче изменить реализацию, проще сделать код тестируемым и так далее ...

Надеюсь, это поможет.

Смежные вопросы