Почему мы используем интерфейс? Это только для стандартизации? [закрыто]

79

Почему мы используем интерфейс?

Это только для стандартизации?

Азхар
источник
1
в отличие от ...? интерфейсы имеют много применений ...
Джейсон
6
Я действительно хочу, чтобы люди не помещали теги вроде C # в сообщения, не относящиеся к C #. Это действительно отличный вопрос, и я, возможно, пропустил его, потому что C # - это игнорируемый тег.
Тайлер Картер

Ответы:

171

Цели интерфейсов

  • создавать слабосвязанное программное обеспечение
  • сопровождение проектирования по контракту (разработчик должен предоставить весь интерфейс)
  • разрешить подключаемое программное обеспечение
  • позволять различным объектам легко взаимодействовать
  • скрыть детали реализации классов друг от друга
  • облегчить повторное использование программного обеспечения

Аналогия 1 : подобно американскому космическому шаттлу, российский космический корабль «Союз» и китайский «Шэньчжоу-5» могут стыковаться с Международной космической станцией, потому что они реализуют один и тот же стыковочный интерфейс. (Это всего лишь пример - я не знаю, правда ли это в реальной жизни, но давайте оставим наше недоверие ради примера)

Аналогия 2 : Например, вы можете подключить к домашнему компьютеру различные компьютерные мониторы. Вы можете подключить к нему телевизор во всю стену, старую ЭЛТ (толстую), 20-дюймовый плоский экран или машину Брайля, чтобы слепые могли "видеть" на ощупь. Эти различные устройства совместимы с вашими компьютер, потому что все они согласны со стандартами интерфейса.

Подробная информация об интерфейсах C #. С интерфейсами C # / OOP вы делаете то же самое, но в невидимом / виртуальном мире.

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

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

John K
источник
18
Вы не упомянули о моем любимом использовании интерфейсов: тестируемость. Если у меня есть два класса, A и B, и A.foo вызывает B.bar, то до тех пор, пока B реализует интерфейс и может быть «введен» в A, я могу использовать фиктивный, поддельный или заглушенный класс вместо реальный B. Это особенно полезно, когда A.foo изменяет свое поведение на основе возвращаемого значения B.bar. (Скажем, B.bar возвращает bool. A.foo может иметь оператор if (B.bar) с предложением else.) Использование интерфейса в B позволяет мне создавать mockB, fakeB и / или stubB, которые позволяют мне проверить, что происходит, когда B.bar возвращает истину или ложь.
aridlehoover
@Alan R - добавлена ​​возможность тестирования. Благодарю.
John K
1
Принятый ответ - ТОП, и приятно видеть, что концепция не отбрасывается, поскольку большинство материалов руководящих принципов разработки фреймворков не могут ее объяснить или понять. Просто добавлю, что если вы серьезно используете Generics, я не знаю, как вы вообще обходились без них.
rama-jka toti
6
+1 дляstandardization, but also flexibility, scalability, extensibility, maintainability, reusability, testability and power.
Ravi
29

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

Например:

public interface IMyInterface{
    public void DoFirst();
    public int DoSecond();
}


public class A : IMyInterface{
   //class has to implement DoFirst and DoSecond
   public void DoFirst(){
     Console.WriteLine("Blubb1");  
   }

   public int DoSecond(){
     Console.WriteLine("Blubb2");
     return 2;  
   }
}

public class B : IMyInterface{
   //class has to implement DoFirst and DoSecond
   public void DoFirst(){
     Console.WriteLine("Blibb1");  
   }

   public int DoSecond(){
     Console.WriteLine("Blibb2");  
     return 4;
   }
}

Классы реализуют интерфейс несколькими способами. Но вы можете использовать их как IMyInterface. Например:

public static void DoMethodsInInterface(IMyInterface inter){
    inter.DoFirst();
    inter.DoSecond();
}


public static void main(){

   DoMethodsInInterface(new A());
   DoMethodsInInterface(new B());
   //Or use it in a List
   List<IMyInterface> interlist = new List<IMyInterface>();
   interlist.Add(new A());
   interlist.Add(new B());
   foreach(IMyInterface inter in interlist){
      inter.DoFirst();
   }

}

Надеюсь, это проясняет, почему интерфейсы полезны.

Мартин
источник
2
Этот вопрос связан с вопросом, в котором спрашивается, зачем использовать интерфейсы, а не просто иметь членов, которые выполняют соответствующие функции и т. Д., И ваш ответ наиболее близок к ответу на этот вопрос. Если два несвязанных класса имеют метод Woozle, любой код, который хочет принять ссылку на любой из классов Woozle, должен знать, с каким классом он имеет дело, и сможет только Woozleклассы, о которых он знает. Напротив, если оба класса реализуются IWoozler, то код, который предоставляется любому, IWoozlerможет Woozleбез необходимости знать его точный тип.
supercat
Этот ответ лучше, чем все, что я видел. Все дело в том, что может делать объект. Интерфейсы определяют набор действий, связанных с объектом, не диктуя, что происходит внутри этих действий, которые, очевидно, будут специфичными для объекта.
m12lrpv
5

Это для взаимодействия :), чтобы вы могли взаимодействовать между собой, это полезно, когда у вас есть

  • несколько реализаций одного и того же материала
  • когда вы применяете интерфейс к нескольким различным классам, потому что вам нужно какое-то соглашение о том, что эти классы могут делать какие-то вещи или иметь некоторые функции
Ому
источник
3

Вот вид на высоком уровне ...

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

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

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

matt_dev
источник
2

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

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

Каталин DICU
источник
1
Интерфейсы на управляемых языках НЕ заменяют множественное наследование. И даже в языках, поддерживающих множественное наследование, концепция интерфейса без реализации актуальна и полезна. (См. Инъекцию зависимостей.)
aridlehoover
1
-1 не очень продуманно, или ты правда не понимаешь C # или Java?
Джон Сондерс,
Все, что я хочу сказать, это то, что в C ++ вместо интерфейсов можно использовать чистые абстрактные классы. Большинство вещей, которые вы можете делать на Java / C # с интерфейсами, вы можете делать на C ++ с чисто абстрактными классами. В C ++, если вы хотите, чтобы у класса было несколько вариантов поведения, вы бы унаследовали несколько чистых абстрактных классов. Но на Java / C # этого сделать нельзя. Я не говорю, что интерфейсы «бесполезны», я говорю больше: такие языки, как Java и C #, на самом деле не были бы объектно-ориентированными языками программирования без множественного наследования интерфейсов. (они не допускают множественного наследования классов или миксинов)
Catalin DICU
1
+1 Это, по сути, то, что было открыто на собственном горьком опыте в C # и Java. Если вы попытаетесь упростить, избегая множественного наследования, вы просто создадите сложность в другом месте. Из-за отсутствия унифицирующего базового подхода вы получите еще более сложную сложность. См. Аннотацию Кшиштофа Квалины в C # Programming Language 3rd Edition , 1.9 Interfaces, в которой говорится именно об этом. На данный момент в C # и Java все еще остаются нерешенные проблемы, которые имели бы простые решения, если бы было разрешено множественное наследование классов.
Дэниел Эрвикер,
-1 наследование и интерфейсы действительно очень разные.
Кенни
2

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

Габриэль Щербак
источник
1

Подумайте об удалении ...

Здесь задействованы клиент и сервер. Допустим, они физически разделены Интернетом. Клиент вызывает метод, фактическое выполнение которого происходит на сервере. С точки зрения клиента, клиент ничего не знает об объекте на сервере, который выполняет выполнение. Однако он знает, какой метод вызвать. Потому что при создании клиентской программы мы видим только интерфейс (или контракт). Нам не доступен весь объект, который фактически живет на сервере. Попробуйте сделать несколько демонстрационных приложений в .net remoting, и вы разберетесь с остальным. Удачного программирования.

deostroll
источник
0

Почему мы используем интерфейсы?

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

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

Алекс Жасмин
источник
0

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

lmsasu
источник
0

Интерфейс отделяет тип данных от логики реализации.

Ананд
источник
0

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

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

потому что класс может реализовывать несколько интерфейсов.

Манодж Гупта
источник
0

Если кто-то похож на меня и учится на примерах и действиях, а не только на объяснениях, вот код ....

Я нашел эту реализацию нейронной сети на C #, включая загрузку проекта, которая использует интерфейсы элегантным и полезным образом:

http://www.c-sharpcorner.com/UploadFile/rmcochran/AI_OOP_NeuralNet06192006090112AM/AI_OOP_NeuralNet.aspx

Дэйв
источник