Как узнать, когда создавать интерфейс?

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

Я часто читаю о них, но кажется, что я не могу их понять.

Я читал такие примеры, как: базовый класс для животных, с интерфейсом IAnimal для таких вещей, как "Прогулка", "Запуск", "GetLegs" и т.д., но я никогда не работал над чем-то и чувствовал себя "Эй, я должен используйте здесь интерфейс!"

Что мне не хватает? Почему мне так сложно понять? Меня просто запугивает тот факт, что я, возможно, никогда не осознаю конкретной потребности в одном - в основном из-за недостатка в их понимании! Это заставляет меня чувствовать, что мне не хватает чего-то высшего в плане того, чтобы быть разработчиком! Если у кого-то был такой опыт и был прорыв, я был бы признателен за некоторые советы о том, как понять эту концепцию. Спасибо.

Ответ 1

он решает эту конкретную задачу:

у вас есть a, b, c, d из 4 разных типов. во всем вашем коде есть что-то вроде:

a.Process();
b.Process();
c.Process();
d.Process();

почему бы им не реализовать IPprocessable, а затем сделать

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

это значительно улучшится, если вы добавите, скажем, 50 типов классов, которые все делают одно и то же.


Другая конкретная проблема:

Вы когда-нибудь смотрели System.Linq.Enumerable? Он определяет тонну методов расширения, которые работают на любом типе, который реализует IEnumerable. Поскольку все, что реализует IEnumerable, в основном говорит: "Я поддерживаю итерацию в неупорядоченном шаблоне типа foreach", вы можете определить сложные поведения (Count, Max, Where, Select и т.д.) Для любого перечислимого типа.

Ответ 2

Мне нравится, что Джимми много отвечает, но я чувствую, что мне нужно что-то добавить. Ключом к этому является "способный" в IProcess . Он указывает на способность (или свойство, но значение "внутреннее качество", а не в смысле свойств С#) объекта, реализующего интерфейс. IAnimal, вероятно, не очень хороший пример для интерфейса, но IWalkable может быть хорошим интерфейсом, если ваша система имеет много вещей, которые могут ходить. У вас могут быть уроки, полученные от Animal, таких как Dog, Cow, Fish, Snake. Первые два, вероятно, будут реализовывать IWalkable, последние два не ходят, поэтому они не будут. Теперь вы спрашиваете: "Почему бы просто не получить еще один суперкласс" WalkingAnimal ", из которого вышла Собака и Корова?". Ответ заключается в том, что у вас есть что-то совершенно вне дерева наследования, которое также может ходить, например, робота. Робот будет реализовывать IWalkable, но, вероятно, не будет получен от Animal. Если вам нужен список вещей, которые можно ходить, вы вводите его как IWalkable, и вы можете поместить всех ходячих животных и роботов в список.

Теперь замените IWalkable на нечто большее, чем программное обеспечение, подобно IPersistable, и аналогия становится намного ближе к тому, что вы увидите в реальной программе.

Ответ 3

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

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

Ответ 4

Подумайте о интерфейсе, таком как Контракт. Это способ сказать: "Эти классы должны следовать этим правилам".

Итак, в примере IAnimal это способ сказать: "Я ДОЛЖЕН иметь возможность вызывать Run, Walk и т.д. на классах, которые реализуют IAnimal".

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

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

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

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

Путем программирования против интерфейса вы, по сути, доверяете классам для реализации намерения интерфейса. Таким образом, в нашем примере мы подумали: "Мне все равно, как они бегут и ходят, пока они бегут и ходят. Мой RunThenWalk будет действителен до тех пор, пока они выполнят это соглашение. Он отлично функционирует, не зная ничего о себе класс."

В обсуждается этот вопрос.

Ответ 5

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

Пример, который я всегда даю кому-то, - это если у вас есть класс Sailboat и класс Viper. Они наследуют класс лодки и класс автомобилей соответственно. Теперь скажите, что вам нужно пройти все эти объекты и вызвать их метод Drive(). Хотя вы могли бы написать какой-то код, как показано ниже:

if(myObject is Boat)
    ((Boat)myObject).Drive()
else
    if (myObject is Car)
        ((Car)myObject).Drive()

Было бы намного проще написать:

((IDrivable)myObject).Drive()

Ответ 6

У Jimmy все правильно, если вы хотите использовать одну переменную для нескольких типов, но все эти типы реализуют один и тот же метод с помощью объявления интерфейса. Затем вы можете назвать их основным методом для типизированной переменной интерфейса.

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

Ответ 7

Мне нравится армейская аналогия.

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

uml

проще для сержанта не беспокоиться о конкретных деталях лиц, с которыми он работает,

рассматривайте всех как абстракции солдат (... и наказывайте их, когда они не могут действовать как те).

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

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

Необходимость для абстрактных деталей для достижения простоты - ответ на ваш вопрос.

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

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

Ответ 8

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

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

EDIT. Чтобы уточнить, с модульным тестированием и издевательством, у меня всегда есть две реализации - настоящая конкретная реализация и альтернативная макетная реализация, используемая при тестировании. Когда у вас есть две реализации, значение интерфейса становится очевидным - справляйтесь с ним в терминах интерфейса, чтобы вы могли в любой момент заменить его. В этом случае я заменяю его макетным интерфейсом. Я знаю, что могу сделать это без реального интерфейса, если мой класс построен правильно, но использование реального интерфейса усиливает это и делает его более чистым (понятным для читателя). Без этого стимула я не думаю, что я бы оценил ценность интерфейсов, поскольку большинство моих классов только когда-либо имели одну конкретную реализацию.

Ответ 9

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

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

Страны имеют стандартные железнодорожные манометры. Это позволяет разделение труда между инженерными компаниями, которые ставят рельсы и инженерные компании, которые строят поезда для работы на этих рельсах, и это позволяет железнодорожным компаниям заменять и модернизировать. > поезда без перестройки всей системы.

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

Примеры из природы: я не слишком увлечен примерами utes(), hasSound(), move() и т.д. Они описывают поведение, которое является правильным, но они не описывают взаимодействия и как они включены. Очевидные примеры интерфейсов, которые позволяют взаимодействовать в природе, связаны с репродукцией, например, цветок обеспечивает определенный интерфейс пчелы, так что опыление может иметь место.

Ответ 10

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

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

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

  • В нашей межмашинной системе обмена сообщениями классы сообщений реализуют определенный интерфейс и "разворачиваются" с помощью интерфейса.

  • Наша система управления конфигурацией определяет интерфейс, используемый для установки и получения настроек конфигурации.

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

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

Ответ 11

Пример кода (комбинация Эндрю с лишним из моих в what-is-the-purpose-of-interfaces), который также приводит пример о том, почему интерфейс вместо абстрактного класса на языках без поддержки множественного наследования (С# и java):

interface ILogger
{
    void Log();
}
class FileLogger : ILogger
{
    public void Log() { }
}
class DataBaseLogger : ILogger
{
    public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
    public void Log() { }
}

Обратите внимание, что FileLogger и DataBaseLogger не нуждаются в интерфейсе (может быть абстрактным базовым классом Logger). Но учтите, что вам необходимо использовать сторонний регистратор, который заставляет вас использовать базовый класс (скажем, он предоставляет защищенные методы, которые вам нужно использовать). Поскольку язык не поддерживает множественное наследование, вы не сможете использовать подход абстрактного базового класса.

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

Ответ 12

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

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

Другим практическим примером является интерфейс ActionListener (или Runnable). Вы бы реализовали их, когда вам нужно отслеживать определенное событие. Поэтому вам необходимо предоставить реализацию метода actionPerformed(Event e) в вашем классе (или подклассе). Аналогично, для интерфейса Runnable вы предоставляете реализацию для метода public void run().

Кроме того, вы можете реализовать эти интерфейсы любым количеством классов.

Другой экземпляр, где используются интерфейсы (в Java), заключается в реализации множественного наследования, предлагаемого на С++.

Ответ 13

Я использовал интерфейсы время от времени, и здесь мое последнее использование (имена были обобщены):

У меня есть набор настраиваемых элементов управления в WinForm, которые должны сохранять данные в моем бизнес-объекте. Один из подходов состоит в том, чтобы вызывать каждый элемент управления отдельно:

myBusinessObject.Save(controlA.Data);
myBusinessObject.Save(controlB.Data);
myBusinessObject.Save(controlC.Data);

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

Я изменил свои элементы управления для реализации интерфейса ISaveable, который имеет метод SaveToBusinessObject (...), поэтому теперь мой метод "Сохранить данные" просто выполняет итерации с помощью элементов управления, и если он находит тот, который является ISaveable, он вызывает SaveToBusinessObject. Итак, теперь, когда нужен новый элемент управления, все, что нужно сделать, это реализовать ISaveable в этом объекте (и никогда не касаться другого класса).

foreach(Control c in Controls)
{
  ISaveable s = c as ISaveable;

  if( s != null )
      s.SaveToBusinessObject(myBusinessObject);
}

Часто нереализованная польза для интерфейсов заключается в том, что вы локализуете модификации. После определения вы редко меняете общий поток приложения, но вы часто вносите изменения на уровне детализации. Когда вы сохраняете детали в конкретных объектах, изменение в ProcessA не повлияет на изменение в ProcessB. (Базовые классы также дают вам это преимущество.)

EDIT: Еще одно преимущество - это специфичность действий. Как и в моем примере, все, что я хочу сделать, это сохранить данные; Мне все равно, какой тип контроля он или может сделать что-нибудь еще - я просто хочу знать, могу ли я сохранить данные в элементе управления. Это делает мой код сохранения довольно понятным - нет проверок, чтобы увидеть, является ли он текстовым, числовым, логическим или каким-либо другим, поскольку пользовательский элемент управления обрабатывает все это.

Ответ 14

Самый простой пример - это что-то вроде Платежных процессоров (Paypal, PDS и т.д.).

Предположим, вы создали интерфейс IPaymentProcessor с методами ProcessACH и ProcessCreditCard.

Теперь вы можете реализовать конкретную реализацию Paypal. Эти методы называют специальными функциями PayPal.

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

Ответ 15

Если вы просматриваете сборки .NET Framework и переходите к базовым классам для любого из стандартных объектов, вы увидите много интерфейсов (членов, названных ISomeName).

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

Классы реализуют интерфейсы, когда они хотят иметь возможность участвовать в структуре явно или неявно. Например, IDisposable - это общий интерфейс, который обеспечивает подпись метода для популярного и полезного метода Dispose(). В рамках всего, что вам или другому разработчику нужно знать о классе, является то, что если он реализует IDisposable, то вы знаете, что ((IDisposable) myObject).Dispose() доступен для вызова для целей очистки.

КЛАССИЧЕСКИЙ ПРИМЕР: без реализации интерфейса IDisposable вы не можете использовать конструкцию ключевых слов "using()" в С#, потому что это требует, чтобы любой объект, указанный как параметр, мог быть неявно передан в IDisposable.

КОМПЛЕКСНЫЙ ПРИМЕР: Более сложным примером может быть класс System.ComponentModel.Component. Этот класс реализует как IDisposable, так и IComponent. Большинство, если не все, объекты .NET, имеющие связанный с ними визуальный дизайнер, реализуют IComponent, чтобы среда IDE могла взаимодействовать с компонентом.

Выводы: Познакомившись с .NET Framework, первое, что вы будете делать, когда встретите новый класс в обозревателе объектов или в инструменте .NET Reflector (бесплатно) (http://www.red-gate.com/products/reflector/) - проверить, какой класс он наследует, а также интерфейсы, которые он реализует..NET Reflector даже лучше, чем Object Browser, потому что он позволяет также видеть классы Derived. Это позволяет вам узнать обо всех объектах, которые происходят из определенного класса, тем самым потенциально узнавая о функциональности фреймворка, которые вы не знали. Это особенно важно, когда обновленные или новые пространства имен добавлены в .NET Framework.

Ответ 16

Он также позволяет выполнять тестирование модульных модулей (.Net). Если ваш класс использует интерфейс, вы можете издеваться над объектом в своем модульном тестировании и легко тестировать логику (без фактического попадания в базу данных, веб-сервис и т.д.).

http://www.nmock.org/

Ответ 17

Предположим, вы хотите захотеть моделировать неприятности, которые могут возникнуть при попытке заснуть.

Модель перед интерфейсами

введите описание изображения здесь

class Mosquito {
    void flyAroundYourHead(){}
}

class Neighbour{
    void startScreaming(){}
}

class LampJustOutsideYourWindow(){
    void shineJustThroughYourWindow() {}
}

Как вы ясно видите, многие вещи могут быть раздражающими, когда вы пытаетесь спать.

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

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

class TestAnnoyingThings{
    void testAnnoyingThinks(Mosquito mosquito, Neighbour neighbour, LampJustOutsideYourWindow lamp){
         if(mosquito != null){
             mosquito.flyAroundYourHead();
         }
         if(neighbour!= null){
             neighbour.startScreaming();
         }
         if(lamp!= null){
             lamp.shineJustThroughYourWindow();
         }
    }
}

Модель с интерфейсами

Чтобы преодолеть эту проблему, мы можем ввести iterface ввести описание изображения здесь

interface Annoying{
   public void annoy();

}

И реализовать его внутри классов

class Mosquito implements Annoying {
    void flyAroundYourHead(){}

    void annoy(){
        flyAroundYourHead();
    }
}

class Neighbour implements Annoying{
    void startScreaming(){}

    void annoy(){
        startScreaming();
    }
}

class LampJustOutsideYourWindow implements Annoying{
    void shineJustThroughYourWindow() {}

    void annoy(){
        shineJustThroughYourWindow();
    }
}

Использование с интерфейсами

Что облегчит использование этих классов

class TestAnnoyingThings{
    void testAnnoyingThinks(Annoying annoying){
        annoying.annoy();
    }
}

Ответ 18

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

Ответ 19

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

Хорошим примером этого в мире .NET является IDisposable интерфейс, который используется на любых классах Microsoft, которые используют систему ресурсы, которые должны быть вручную выпущены. Это требует, чтобы класс, реализующий его, имел метод Dispose().

(Метод Dispose() также вызывается конструкцией языка использования для VB.NET и С#, который работает только на IDisposable s)

Имейте в виду, что вы можете проверить, реализует ли объект определенный интерфейс, используя такие конструкции, как TypeOf ... Is (VB.NET), is (С#), instanceof (Java) и т.д.

Ответ 20

Как уже, наверное, уже ответили несколько человек, интерфейсы могут использоваться для обеспечения определенных действий между классами, которые не будут реализовывать эти поведения одинаково. Поэтому, реализуя интерфейс, вы говорите, что ваш класс имеет поведение интерфейса. Интерфейс IAnimal не будет типичным интерфейсом, поскольку классы Dog, Cat, Bird и т.д. Являются типами животных и, вероятно, должны расширять его, что является случаем наследования. Вместо этого интерфейс будет больше похож на поведение животных в этом случае, например, IRunnable, IFlyable, ITrainable и т.д.

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

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

Я бы рекомендовал прочитать главу о интерфейсах в Java Design от Coad, Mayfield и Kern. Они объясняют это немного лучше, чем средний вводный текст. Если вы не используете Java, вы можете просто прочитать начало главы, которая в основном является концепцией.

Ответ 21

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

Существует компромисс здесь, как обычно: гибкость над ремонтопригодностью. Какой из них более важен? Ответов нет - это зависит от проекта. Но просто помните, что каждое программное обеспечение должно поддерживаться...

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

Сказав это, когда вам нужно создать интерфейс?

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

И он работает: o)

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

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

С уважением, Сильвен.

Ответ 22

Существует так много целей для использования интерфейса.

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

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

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

Например, IUser, IOrder, IOrderItem

public interface IUser()
{

void AddUser(string name ,string fname);

}

// Same for IOrder and IOrderItem
//


public class  BusinessLayer: IUser, IOrder, IOrderItem

{    
    public void AddUser(string name ,string fname)
    {
        // Do stuffs here.
    }

    // All methods from all interfaces must be implemented.

}

Если вы хотите добавить пользователя, сделайте следующее:

IUser user = new (IUser)BusinessLayer();

// It will load  all methods into memory which are declared in the IUser interface.

user.AddUser();

Ответ 23

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

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

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

Также см. этот вопрос о кодировании для интерфейса.

Ответ 24

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

Мы можем иметь интерфейс Gun, который определяет функцию shoot().

Нам нужны разные подклассы класса Gun, а именно ShotGun Sniper и т.д.

ShotGun implements Gun{
    public void shoot(){
       \\shotgun implementation of shoot.
    } 
}

Sniper implements Gun{
    public void shoot(){
       \\sniper implementation of shoot.
    } 
}

Класс шутера

У стрелка есть все оружие в его Доспехе. Позволяет создать List для его представления.

List<Gun> listOfGuns = new ArrayList<Gun>();

Стрелок проводит через свои пушки, когда и когда это необходимо, используя функцию switchGun()

public void switchGun(){
    //code to cycle through the guns from the list of guns.
    currentGun = //the next gun in the list.
}

Мы можем установить текущий пистолет, используя указанную выше функцию, и просто вызвать функцию shoot(), когда вызывается fire().

public void fire(){
    currentGun.shoot();
}

Поведение функции съемки зависит от разных реализаций интерфейса Gun.

Заключение

Создайте интерфейс, когда функция класса зависит от функции из другого класса, которая подвержена изменению ее поведения на основе экземпляра (объекта) реализованного класса.

например. Функция fire() из класса Shooter ожидает пушки (Sniper, ShotGun) для реализации функции shoot(). Поэтому, если мы включим пистолет и огонь.

shooter.switchGun();
shooter.fire();

Мы изменили поведение функции fire().