Чому ми використовуємо інтерфейс? Це лише для стандартизації? [зачинено]


79

Чому ми використовуємо інтерфейс?

Це лише для стандартизації?


1
на відміну від ...? інтерфейси мають багато застосувань ...
Джейсон

6
Я дуже хочу, щоб люди не розміщували теги, такі як c #, на публікаціях, які не є специфічними для c #. Це справді чудове запитання, і я міг би його пропустити, тому що c # - це ігнорований тег.
Тайлер Картер,

Відповіді:


171

Призначення інтерфейсів

  • створювати вільно пов'язане програмне забезпечення
  • підтримка дизайну за контрактом (реалізатор повинен надати весь інтерфейс)
  • дозволяють підключати програмне забезпечення
  • дозволяють різним об’єктам легко взаємодіяти
  • приховувати деталі реалізації класів один від одного
  • полегшити повторне використання програмного забезпечення

Аналогія 1 : Подібно до американського космічного човника, російський космічний корабель "Союз" і китайський "Шеньчжоу-5" можуть причалити до Міжнародної космічної станції, оскільки вони використовують той самий док-інтерфейс. (Це лише приклад - я не знаю, чи це правда в реальному житті, однак давайте припинимо нашу невіру заради прикладу)

Аналогія 2 : Як ви можете підключити різні монітори комп’ютерів до домашнього комп’ютера. Ви можете підключити до нього настінний телевізор, старий ЕПТ (товстий), 20-дюймовий плоский екран або брайлівський апарат для сліпих, щоб "бачити" на дотик. Ці різні / різні пристрої сумісні з комп’ютер, оскільки всі вони погоджуються на стандарти інтерфейсу.

Деталі інтерфейсів C # - з інтерфейсами C # / OOP ви робите те саме, але у невидимому / віртуальному світі.

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

(Чим більше ви будете використовувати програмні інтерфейси, тим більше будуть зрозумілі ці "слівця". І завжди враховуйте інтерфейси в реальному світі, тому що вони зробили нас однаково добре)


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 повертає true або false.
aridlehoover

@Alan R - додано випробуваність. Дякую.
John K

1
Прийнята відповідь - це ТОП речі, і радісно бачити, що концепція не відкидається, оскільки більшість матеріалів керівних принципів проектування не можуть пояснити або зрозуміти її. Просто додавши, що якщо ви серйозно використовуєте Generics, я не знаю, як ви колись проходили без них.
rama-jka toti

6
+1 заstandardization, but also flexibility, scalability, extensibility, maintainability, reusability, testability and power.
Раві

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

Ось вид на високому рівні ...

Інтерфейси відіграють велику роль у концепції приховування інформації .

Вони в основному допомагають вам приховати деталі реалізації вашого класу, так що викликаючий клас не має залежності від цієї реалізації. Отже, за допомогою інтерфейсів ви можете модифікувати реалізацію без зміни класу виклику. Це все в свою чергу обмежує складність вашого коду і полегшує його підтримку в довгостроковій перспективі.

Коли я вперше почав розуміти інтерфейси, вони пояснили мені це як "контракт, що містить опис вашого класу". Не впевнений, чи це допоможе вам, але якщо ви думаєте про інтерфейс для автомобіля, ви можете сказати, що він їде , ламається та повертається . Отже, поки я потрапляю з пункту А в пункт Б, я насправді не повинен знати, як ці функції реалізовані.


2

Основна причина, по якій інтерфейси використовуються в таких мовах, як C # / Java, полягає в тому, що ці мови не підтримують множинне (клас) успадкування (див. Яка точна проблема багаторазового успадкування? ).

Але багаторазова реалізація (інтерфейс) дозволена, що дозволяє використовувати класи по-різному.


1
Інтерфейси в керованих мовах НЕ замінюють багаторазове успадкування. І навіть у мовах, які підтримують множинне успадкування, концепція інтерфейсу без реалізації є релевантною та корисною. (Див. Ін’єкцію залежності.)
aridlehoover

1
-1 не дуже добре продуманий, чи ви справді не розумієте C # чи Java?
Джон Сондерс,

Все, що я хочу сказати, це те, що в C ++ замість інтерфейсів можна використовувати чисто абстрактні класи. Більшість речей, які ви можете робити в Java / C # з інтерфейсами, ви можете робити в C ++ із чисто абстрактними класами. У C ++, якщо ви хочете, щоб клас мав кілька поведінок, ви успадковуєте кілька чистих абстрактних класів. Але ви не можете цього зробити в Java / C #. Я не кажу, що інтерфейси не є "корисними", я кажу більше того: такі мови, як Java & C #, насправді не були б об'єктно-орієнтованими мовами програмування без успадкування декількох інтерфейсів. (вони не дозволяють успадкування кількох класів, ні міксини)
Catalin DICU

1
+1 Це по суті те, що було важко виявлено досвідом C # та Java. Якщо ви намагаєтеся спростити, уникаючи багаторазового успадкування, ви просто створюєте складність в іншому місці. Через відсутність уніфікуючого підходу в підсумку ви отримуєте гіршу складність. Див. Анотацію Кшистофа Кваліни в мові програмування C # 3-е видання , 1.9 Інтерфейси, де сказано саме це. На сьогоднішній день у C # та Java все ще є невирішені проблеми, які мали б прості рішення, якщо було дозволено багаторазове успадкування класів.
Даніель Ервікер

-1 успадкування та інтерфейси насправді дуже різні.
kenny

2

Інтерфейси дещо незграбні. Вони підтримують дизайн за контрактом, просто вірячи, що однакові назви та реалізований інтерфейс означають однакову поведінку. Це працює лише завдяки документації API, вона повинна бути перевірена людиною. Це робить інтерфейси занадто слабкими. Одним із способів обійти це можуть бути офіційні специфікації. З іншого боку, інтерфейси занадто міцні, занадто суворі. Ви не можете розвивати інтерфейси, які часто заважають повторному використанню. Це вирішується протоколами - механізмом на динамічних мовах, які надсилають повідомлення (методи виклику), а коли це повідомлення не підтримується одержувачем, викликається стандартний зворотний виклик. Наявність конкретних протоколів з обмеженнями було б краще.


1

Подумайте про віддалення ...

Тут задіяний клієнт і сервер. Скажімо, їх фізично розділяє Інтернет. Клієнт викликає метод, фактичне виконання якого відбувається на сервері. З точки зору клієнта, клієнт не знає нічого про об'єкт на сервері, який виконує виконання. Однак він знає, який метод викликати. Оскільки, будуючи клієнтську програму, ми стикаємось лише з інтерфейсом (або контрактом). Ми не потрапляємо під дію всього об’єкта, який насправді живе на сервері. Спробуйте зробити деякі демонстраційні програми в .net віддаленому, і ви зрозумієте все інше. Щасливого програмування.


0

Чому ми використовуємо інтерфейси?

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

Тож колись ми просто використовуємо інтерфейси, оскільки мовний дизайн цього вимагає.


0

Починаючи з інтерфейсу, ви можете реалізувати проксі-сервер , тим самим дозволяючи ліниве завантаження або виконуючи деякі перевірки при виклику методів конкретної реалізації.



0

Інтерфейс забезпечує прототип модального, який просто містить декларацію про функціональність конкретної поведінки.

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

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


0

Якщо хтось ще схожий на мене і вчиться на прикладах і вчинках, а не лише на поясненнях, ось якийсь код ....

Я знайшов цю реалізацію нейронної мережі в C #, включаючи завантаження проекту, яка використовує інтерфейси елегантно та корисно:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.