[C#] Зачем нужны интерфейсы?
Для уменьшения зависимостей между частями приложения
что такое "часть приложения"? сборки, классы?
Пофигу. Главное, что одна часть может не знать, как реализована другая.
такую фразу можно сказать даже о процедурном прогрммировании. Одна функция не знает как реализована другая функция. Там интерфейсов нет.
процедурное программирование не позволяет хранит это описание в удобном виде. Максимум, ты можешь вынести хедэр отдельно.
Да, в обычном C можно сделать некоторый аналог интерфейсов, через указатели на функции, но это неудобно и непрозрачно. А так у тебя уже в языке есть конструкция, с помощью которой какой-то кусок кода может работать с другим куском кода через этот интерфейс, а уж на какой момент будет написан этот код, не важно.
Можно на обычном C реализовать и виртуальные функции, и интерфейсы - только это лишняя работа, никому не нужная.
что значит в удобном? в удобном для чего?
Оставим возможности обычного С. По существу вопроса -- интерфейсы нужны для того, чтобы была возможность писать клиентский код раньше, чем будет реализована функциональность? Методов-заглушек для этого не достаточно?
для программера. Одно дело, знать гуид (и даже, на самом деле, какие-нибудь ключевые слова для поиска в реестре) комплекта функций, другое дело, знать, в каком файле вбиты хедеры, в каком - имплементация.
чтобы надежно заменять компоненты
вообще-то тред про C#, там ни реестра, ни файлов с хедерами нет, там есть сборки.
Интерфейс говорит, что точно умеет (со стороны пользователя объектов класса) и что должен уметь (со стороны разработчика класса, реализующего заданный интерфейс) объект данного класса.
соглашения между автором класса и пользователем класса на определенную функциональность объектов класса
или в шарпе вообще интерфейсы есть, а компоненты никто не ищет?
> ни файлов с хедерами нет
хедеры были приведены для сравнения
или в шарпе вообще интерфейсы есть, а компоненты никто не ищет?ну типа того. Во много похоже на Java, если что
Иии...?
публичные элементы класса тоже заключают
Ты хочешь выяснить, зачем нужны интерфейсы, если есть классы - так?
Класс содержит данные и действия.
Интерфейс описывает только поведение класса. И не важно, как это реализует класс. Важно, что он это делает и все.
Не знаю, как с C#, но в Яве, afaik, интерфейсы придумали как альтернативу множественному наследованию в C++, для упрощения реализации и большей строгости, что-ли... Подозреваю, что в C# тоже самое.
я думал, шарп использует интерфейсы, как КОМ.
а какая тут альтернатива множественному наследованию, если нельзя пользоваться готовыми методами?
Интерфейс описывает только поведение класса. И не важно, как это реализует класс. Важно, что он это делает и все.Определение интерфейса я знаю
конечно, не альтернатива в полном смысле, но без них было бы еще хуже, если запрещено множественное наследование.
1. Интерфейсы используются когда, требуется, чтобы объект класса A мог быть представлен, как переменная типа IB, но не хочется использовать наследование классов, поскольку наследование классов дифицитная вещь -- может быть только один родитель. А если наследование классов уже есть, тогда интерфейс это единственный вариант.
2. В случае распределенного приложения (Remoting-а) интерфейс позволяет не держать всю серверную сборку на клиенте. Интерфейс определяется в общей сборке, которая лежит и на клиенте и на сервере.
Мне сказали, что это не полный ответ.............
В С#, можно рассматривать с точки зрения реализации: С# интерфейсами реализуется более общий полиморфизм (в отличии от расширения при использовании наследования когда один объект может вести себя как объект двух разных типов (в случае C# такие типы могут определяются только набором поддерживаемых операций, то что наз. интерфейсами) -- на уровне кода, вызовы через C# интерфейс реализованы специальным образом с дополнительным перенаправлением вызова, что дает возможность не зависеть размеру памяти, занимаемой объектом, который реализует множество интерфейсов. Если обходиться одним расширением, то такой вид полиморфизма можно реализовывать делегированием (пример такого подхода -- множественное наследование в С++ но при этом на каждый интерфейс +1 указатель как поле в структуре объекта.
а где банальный ответ: интерфейсы нужны для реализации полиморфизма?
Т.е. на твой вопрос надо отвечать так: в С# с использованием интерфейсов можно ... , для этого они и нужны, т.к. нормального способа такое реализовать другими средствами нет.
то есть это не фича, а костыль?
фича, читай последний пост Даркгрея, я просто раскрыл детали
он говорит про полиморфизм. Полиморфизм там, вроде, сам собой есть. По крайней мере, в плюсплюсе и других старых языках он поддерживается виртуальными функциями, а в джаве он поддерживается сам собой. Вроде, и в шарпе так, или я ошибаюсь?
Интерфейсы в C# для ЭФФЕКТИВНОЙ реализации полиморфизма В СЛУЧАЕ МНОЖЕСТВЕННЫХ ОТНОШЕНИЙ УТОЧНЕНИЯ НА ТИПАХ
детальнее см.
еще детальнее: была статья в MSDN Magazine, кажется Джефри Рихтера, про реализацию интерфейсов (называние не помню).
как быть если общего предка нет, и по смыслу быть не должно, а полиморфизм иметь хочеться?
объект класса A мог быть представлен, как переменная типа IB
у тебя какая-то фигня сказана, из нее беглым взглядом понятие полиморфизма не выцепляется.
причем, во-первых: это логическое понятие, вытекающие из ООП-концепции (а ты какую-то пургу несешь про физические проблемы реализации классов в конкретном языке)
во-вторых: гарантируется, что эти грани могут быть независимыми друг от друга (классы это не гарантируют)
void f(IC c)
{
c.g;
}
и мы хотим, чтобы он принимал объекты типа A и типа B. Реализация метода g требуется везде одинаковая (т.е. полиморфизм не нужен). Если бы не было иерархий, то проще унаследовать классы A и B, от базового
class IC
{
public void g {} //не виртуальный
}
А если уже есть иерархии (или мы хотим оставить возможность иерархий то нам надо использовать интерфейс.
интерфейс - это независимая "грань" объекта.вот это действительно пурга из общих слов и отвлеченных аналогий.
причем, во-первых: это логическое понятие, вытекающие из ООП-концепции (а ты какую-то пургу несешь про физические проблемы реализации классов в конкретном языке)
во-вторых: гарантируется, что эти грани могут быть независимыми друг от друга (классы это не гарантируют)
нет, конечно, не проще.
потому что, если у тебя еще есть метод (а в большой системе - так обычно и бывает который принимает:
void f(ID d)
{
d.g;
}
то твое решение уже не пройдет, потому что ты не сможешь сделать разные g у одного класса.
поэтому еще раз подчеркиваю, что интерфейс - это способ, которые позволяет создавать независимые грани объекта.
ps
Самое плохое. что ты рассуждаешь с позиции "почему", а не позиции "зачем", а позиция "почему" очень редко несет какую-то конструктивную информацию.
а ты какую-то пургу несешь про физические проблемы реализации классов в конкретном языкечасто как раз в физической реализации вылезают логические косяки . Кстати, речь не про один язык, а про Java и серию языков .NET-а.
так, никто и не спорит об этом
но какой смысл заострять внимание на косяках, если в первую очередь надо заострять внимание на то, какие задачи/проблемы решает данный подход?
ps
т.е. как знание о косяках - нам позволяет двигаться вперед?
знание косяков - дает нам возможность не набить шишек при движении, но само по себе никакого движения не создает.
т.е. тебе ближе позиция кодера, чем архитектора?
В таких языках как C# и Java все очень завязано на реализацию, где интерфейсами реализуют специальный вид полиморфизма, который на практике очень важен, и который необходимо эффективно реализовывать. Фактически просто нет других вариантов, как можно реализовывать такой множественный полиморфизм, которые давали бы сравнимую эффективность с точки зрения производительности, и дополнительно несли какие-то бонусы.
потому что когда закладывались основы этих языков - это было все что знали/исследовали о контрактах на тот момент.
на данный момент исследовали чуть больше - появились всякие ковариантности и т.д., что возможно будет реализовано в следующих языках в нормальном объеме.
> Так можно дойти и до более конкретных требований, которые фактически определяют реализацию.
тот же Eiffel именно такие требования и поддерживает, и при этом имеют свою нишу при разработке программ.
> С другой стороны, зачем требования на сигнатуры? Чтобы гарантировано вызов x.getCount не выкинул какое-то рантаим эксепшин
откуда ты выкопал какие-то гарантии?
сигнатуры лишь помогают вынести часть runtime-ошибок на уровень компиляции, и еще раз подчеркиваю - что ничего не гарантируют.
Ладно, это я к тому, что нужно определиться с вопросом, есть варианты:
а) вопрос про интерфейсы C#, такие так они есть -- тогда вопрос "зачем они нужны", нужно рассматривать с точки зрения реализации;
б) вопрос про то, как интерфейсами пользоваться в С# -- тогда вопрос "для чего они нужны" нужно рассматриваться с архитектурной точки зрения;
в) вопрос про интерфейсы вообще, в общем контексте ООП -- тогда тут надо начинать философствовать на тему полиморфизма и т.д.
откуда ты выкопал какие-то гарантии?Ты же сам рассматриваешь интерфейс как какой-то контракт, на который может рассчитывать клиент. Ну, так общими словами: гарантии как элементы контракта (мб слово не самое удачное подобрал).
это я не говорил.
я говорил, что более-менее гарантируется, что интерфейсы друг от друга не зависимы.
но я не говорил, что гарантируются какие-то отсутствия runtime-ошибок, или правильность реализации.
интерфейс - это один из способов, понятных компилятору, описания отдельных (но далеко не бОльших) частей контракта между клиентом и сервером.
Так есть же гарантии, что с самим вызовом все ок, и будет выполняться код метода, относительно него конечно никаких гарантий нет. Хотя в Джава есть гарантии относительно исключений, которые генерирует код метода.
с точки зрения контрактов:согласен
интерфейс - это один из способов, понятных компилятору, описания отдельных (но далеко не бОльших) частей контракта между клиентом и сервером.
насколько я понимаю, гарантий тоже никаких нет.
потому что если мы цепляем метод через remoting или через что-то еще, то в том числе будут исключения и этой среды.
Each method of a remote interface, an interface that extends java.rmi.Remote, must list RemoteException in its throws clause.
или, хотя бы, если ты раньше у тебя методы работали с памятью, а теперь ты решил кэшировать часть данных на диск, опять интерфейс менять?
Такое мы проходили, мешает, приходиться извращаться, прятать в RuntimeException, например -- короче это в Джава не самое удачное решение. Просто это реальный пример, когда контракт интерфейса больше чем сигнатуры методов.
нет, конечно, не проще.как это нет? для имплиментации интерфейса ты будешь либо дублировать код, либо заводить дополнительный класс и делигировать вызовы методов -- это дополнительный геморрой, код становится менее читаемым.
то твое решение уже не пройдет, потому что ты не сможешь сделать разные g у одного класса.
что ты хотел сказать приведенным кодом, я не понял. Речь идет о возможности C# explicit interface member implementations?
как это нет? для имплиментации интерфейса ты будешь либо дублировать код, либо заводить дополнительный класс и делигировать вызовы методов -- это дополнительный геморрой, код становится менее читаемым.Подразумевается, что методы интерфейса существенно завязаны на то, что именно происходит в данном классе, то есть дублирования кода просто не может быть. Если ты вдруг чувствуешь, что какой-нибудь интерфейсный метод использует какой-нибудь код, который может быть вынесен в метод сонаследуемого класса (в терминологии С++ реализуй его в качестве статической функции какого-нибудь хелпера.
о чем и речь, это сложнее, чем просто унаследовать
flood.programming at forum.local
Переформулирую вопрос:
1. В каких случаях следует применять интерфейсы?
2. Какие преимущества дают интерфейсы в тех случаях, когда есть другие варианты решения проблемы?
Речь идет о написании кода на языке C#.
1. При разработке разными людьми кода класса и кода его использования
2. для тех случаях, когда сложно сказать - как именно и где именно будет реализовываться данных функционал
(как пример - ICollection, заранее сложно сказать - где именно и как именно функционал стоящий за ICollection будет реализовываться)
3. При разделение кода на крупные независимые единицы
большую независимость.
быстрее (по крайней мере для .net 1.1 чем делегаты
Оставить комментарий
6yrop
как бы вы ответили на такой вопрос?