Защо интерфейсът няма реализация? - ° С#

Четох някаква теория на кода, свързана с множествено наследяване и интерфейси. На всички места пишеше, че interface is a class without implementation.

1) Каква е ползата от липсата на внедрени методи/функции в интерфейс? Трябва ли да поддържа множество реализации на един и същ метод в различни класове, които наследяват интерфейс?

2) Повечето от примерните кодове там изглежда показват void интерфейсни методи. Функциите/методите на интерфейса винаги ли са void?


person aspiring    schedule 15.02.2013    source източник
comment
Трябва да опитате да потърсите малко, преди да публикувате въпрос: тук   -  person bash.d    schedule 15.02.2013
comment
(1) До голяма степен, да. (2) Не е задължително; можете да имате невалидни методи, свойства, събития...   -  person Rawling    schedule 15.02.2013
comment
Може би малко предистория: C# няма множествено наследяване като c. В C бихте могли да имате базов клас с някои методи, 2 (или повече) дъщерни класа на базовия клас и след това клас внук, който наследява и от двата дъщерни класа. Това е известно като проблем с диаманта. Трябва ли внукът да се държи като едно от децата и от кое? java и c# се опитват да избегнат проблеми от това съзвездие, използвайки абстрактен клас, който е интерфейсът. можете да имплементирате някои интерфейси, но не можете да наследявате от повече от един клас.   -  person Offler    schedule 15.02.2013
comment
@Offler, проведох страхотен разговор тук, в SO по MI :) Все пак оценявам приноса ви. Като обобщение на последния раздел на вашия коментар, мога ли да кажа това Class D: A, IB, IC? (IB, IC са два различни интерфейса, така че този клас D наследява от клас A и два интерфейса/абстрактни класа)   -  person aspiring    schedule 15.02.2013
comment
Ако направите нещо като „клас D: A, IB, IC“, вие наследявате от клас A. Ако A има неабстрактни публични методи, можете да ги извикате. С IB казвате само: D съдържа имплементацията за методи, които са декларирани в IB, но нямат код в IB. D имплементира кода, който е необходим, за да действа като IB. Или с други думи: вие наистина наследявате от A, което декларира и дефинира методи, които могат да бъдат използвани; IB показва само коя структура е необходима, че трябва да има нещо с това име, ако имплементирате интерфейса в клас.   -  person Offler    schedule 18.02.2013


Отговори (3)


На въпрос 1: да, това е една от причините да се използват интерфейси. Интерфейсите често се използват като API за компонент. Действителното внедряване може да бъде неизвестно за потребителя, поддържайки хлабаво свързване и възможност за тестване чрез единични тестове.

Относно въпрос 2: не, интерфейсните методи могат да имат същите сигнатури на методите като методите на класа.

person Dirk Trilsbeek    schedule 15.02.2013
comment
Благодаря. Можете ли да предоставите пример за последната причина: Действителното внедряване може да е неизвестно на потребителя, поддържайки хлабаво свързване и възможност за тестване чрез единични тестове.? - person aspiring; 15.02.2013
comment
хлабавото свързване се използва най-вече с контейнери за инжектиране на зависимости като Castle Windsor, Unity, NInject или Spring Framework. За да получите обща представа за DI (или инверсия на контрола като по-общо наименование на шаблона), трябва да разгледате няколко урока, като този: joelabrahamsson.com/entry/ . Относно възможността за тестване: модулните тестове трябва да тестват само една единица, така че тестван компонент, който разчита на (може би много) други компоненти, би било трудно да се тества самостоятелно. Използвайки подигравателни рамки или мъничета, можете да улесните тестването на единици. - person Dirk Trilsbeek; 15.02.2013
comment
Е, това надхвърля шапката ми :) Погледнах този урок по отношение на interface inheritance не в LinQ. Повечето от статиите обаче гласят classes implement interfaces вместо classes inherit from interfaces. Подобно на това, което споменахте в един от вашите коментари. И така, каква е правилната норма? прилага или наследява? Ако е така, защо тази статия ще казва наследява? - person aspiring; 15.02.2013
comment
Наследяването на интерфейса е концепция, при която един интерфейс наследява декларации на метод от друг интерфейс. Внедряването на такъв интерфейс не се различава от прилагането на такъв, който не наследява никакви декларации на методи. - person Dirk Trilsbeek; 15.02.2013

1) Каква е ползата от липсата на внедрени методи/функции в интерфейс? Поддържа ли се множество реализации на един и същи метод в различни класове, които наследяват интерфейс?

ДА.

2) Повечето от примерните кодове там изглежда показват невалидни интерфейсни методи. Функциите/методите на интерфейса винаги ли са невалидни?

Нищо подобно. Може да върне всичко.

person Habib    schedule 15.02.2013
comment
Благодаря. Е, в първия случай все още мога да напиша родителски клас и да наследя неговия конкретен метод и да го внедря по различен начин в множество дъщерни класове.. Успях да го направя. И така, какво е предимството от поставянето на тези методи в интерфейс (освен опитите за заобиколно решение на множествено наследяване)? :) - person aspiring; 15.02.2013
comment
@aspiring, въпросът ви трябва да е Защо да използвате интерфейс? , вие вече споменахте една от причините в коментара си, интерфейсът всъщност дефинира договор и е полезен с полиморфизма. Трябва да прочетете повече за концепцията, това може да е добро начало cs.utah.edu/~germain/PPS/Topics/interfaces.html - person Habib; 15.02.2013
comment
Благодаря :) полезно, цялата помощ и статии. - person aspiring; 15.02.2013

За 1) Да, идеята ви е правилна. Да предположим, че имате интерфейс, който има само някакъв метод makeSound. Сега можете да внедрите този интерфейс в някои Guitar класове и някои Drums класове. Трябва само да знаете във вашата програма, че имате някакъв обект, който имплементира makeSound, за да можете да извикате този метод. Няма нужда да знаете какъв ще бъде действителният изход/звук.

За 2) Не, интерфейсът може да съдържа методи с произволен подпис.

person Dominik Sandjaja    schedule 15.02.2013
comment
Значи имате предвид подобен на Draw() метод в Graphics клас? Но тогава Guitar трябва да дава звук на китара, както и Drums. Да се ​​каже, че когато се внедри този makeSound метод, той ще приеме звука на изпълнението на дъщерния клас? ако беше makeShape, ще приеме формата на дъщерния клас? - person aspiring; 15.02.2013
comment
Ще е необходима най-подходящата реализация. Ако override внедряване, това ще бъде взето. Тъй като Guitar и Drums не се наследяват едно от друго, ще се използва съответното им изпълнение. - person Dominik Sandjaja; 15.02.2013
comment
@aspiring не мислете за реализациите на интерфейса като за дъщерни класове. Интерфейсът е просто нещо като обещание, че обект, прилагащ този интерфейс, ще има метод с име X със сигнатура Y. В примера на DaDaDoms Interface.makeSound всъщност ще бъде Guitar.makeSound, ако вашият обект е китара. И би било Drums.makeSound, ако обектът беше от тип Drums. - person Dirk Trilsbeek; 15.02.2013