Для чего нужно разделение на class и interface?
От: developer  
Дата: 09.12.17 17:16
Оценка:
В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?
Re: Для чего нужно разделение на class и interface?
От: notacat  
Дата: 09.12.17 17:32
Оценка: 2 (1)
D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?
если в языке нет множественного наследования, то унаследоваться выгодней от того класса, который реализует максимум необходимой функциональности. А все остальное — через интерфейсы
Re: Для чего нужно разделение на class и interface?
От: Vladek Россия Github
Дата: 09.12.17 17:48
Оценка: 2 (1)
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


В Java нет множественного наследования классов. У класса может быть только один предок-класс, но допускается множество предков-интерфейсов. Интерфейс — это по сути полностью абстрактный класс, которому нельзя потом случайно добавить неабстрактный метод или поле. Ты видишь интерфейс в коде и понимаешь, что он так и будет оставаться интерфейсом. Это важно, потому что код постоянно изменяется или иначе программа будет становиться всё менее и менее полезной.
Re[2]: Для чего нужно разделение на class и interface?
От: developer  
Дата: 09.12.17 18:03
Оценка: :)
Здравствуйте, Vladek, Вы писали:

V>В Java нет множественного наследования классов. У класса может быть только один предок-класс, но допускается множество предков-интерфейсов. Интерфейс — это по сути полностью абстрактный класс, которому нельзя потом случайно добавить неабстрактный метод или поле. Ты видишь интерфейс в коде и понимаешь, что он так и будет оставаться интерфейсом. Это важно, потому что код постоянно изменяется или иначе программа будет становиться всё менее и менее полезной.


Т.е. единственная причина по которой в Java введены интерфейсы (как отдельные концепции) это то, что в Java нет множественного наследования?

Абстрактный класс то же можно сделать неизменяющимся — объявить его final.
Re: Для чего нужно разделение на class и interface?
От: std.denis Россия  
Дата: 09.12.17 18:20
Оценка: +3
D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface).
Абстрактные классы – средство переиспользования кода, а интерфейсы – средство описания контракта.

D>Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?

Можно. Для большей абстрактности – интерфейс ведь по сути чисто-абстрактный класс без реализаций и данных.
Re[3]: Для чего нужно разделение на class и interface?
От: notacat  
Дата: 09.12.17 18:29
Оценка: +1
D>Т.е. единственная причина по которой в Java введены интерфейсы (как отдельные концепции) это то, что в Java нет множественного наследования?

D>Абстрактный класс то же можно сделать неизменяющимся — объявить его final.

не знаю, как в джаве, но интерфейс это чистая абстракция, договоренность о какой-то функциональности, независимая от реализации. Например у лампочки должен быть выключатель. Методы включить и выключить — это интерфейс. Делать их кнопкой на стене или датчиком, который будет реагировать на движение или звук — это отдельный вопрос. Реализации могут отличаться кучей всего, находиться за три километра или в другом приложении, написанном на другом языке.
Re: Для чего нужно разделение на class и interface?
От: iZEN СССР  
Дата: 09.12.17 19:45
Оценка: -2
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


В конце-концов в ООП пришли к выводу, что наследование == ЗЛО. Для выполнения условий контракта достаточно публичных сигнатур методов и реализации интерфейсов, а методы самих объектов делать публичными необязательно. Это приводит к "плоским" архитектурным решениям, где взаимодействие объектов строится по схеме интерфейсов, которые классы реализуют. А интерфейсы, в свою очередь, прорабатываются наиболее тщательно, так как они отвечают за представление протокола взаимодействия между объектами-сущностями.
Отредактировано 09.12.2017 19:47 iZEN . Предыдущая версия . Еще …
Отредактировано 09.12.2017 19:47 iZEN . Предыдущая версия .
Re[3]: Для чего нужно разделение на class и interface?
От: Nikolay_Ch Россия  
Дата: 09.12.17 19:53
Оценка:
Здравствуйте, developer, Вы писали:

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

В дополнение к тому, что при отсутствии множественного наследования, наследование от интерфейсов становится единственным способом объединять потомков в цепочки наследования, интерфейсы применяются в модульном тестировании (конечно, если код написан правильно, используя DIP).
Re[3]: Для чего нужно разделение на class и interface?
От: bnk СССР http://unmanagedvisio.com/
Дата: 09.12.17 20:41
Оценка:
Здравствуйте, developer,

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


D>Т.е. единственная причина по которой в Java введены интерфейсы (как отдельные концепции) это то, что в Java нет множественного наследования?

D>Абстрактный класс то же можно сделать неизменяющимся — объявить его final.

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

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

Смысл в том, чтобы можно было одинаково использовать разнотипные объекты,
не задумываясь о их конкретном типе типе в месте использования (не писать свитч по типу)
Именно множественное наследование, или возможность реализпции нескольких интерфейсов,
чтобы один и тот же объект можно было использовать таким образом в разных местах.
Отредактировано 09.12.2017 21:10 bnk . Предыдущая версия . Еще …
Отредактировано 09.12.2017 21:08 bnk . Предыдущая версия .
Re[4]: Для чего нужно разделение на class и interface?
От: itslave СССР  
Дата: 11.12.17 14:05
Оценка: +1 -1
Здравствуйте, bnk, Вы писали:

bnk>В плюсах например интерфейсы без проблем заменяются абстрактными классами.


"Без проблем" — это несколько оптимистичненькое заявление. Потому как на вопросы "что такое ромбовидное наследование" и "что такое виртуальное наследование" не каждый сеньор отвечал лет 10 назад.
И одна из основных причин введения интерфейсов — это осмысление опыта С++ и способ избежать треша с ромбовидным наследованием.
Re: Для чего нужно разделение на class и interface?
От: Berill Азербайджан  
Дата: 13.12.17 14:31
Оценка:
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


Вот что пишет Э.Троелсен в своей книге "Язык программирования C# и платформа .Net 4.5"

После изучения главы 6 интерфейсный тип может показаться очень похожим на абстрактный базовый класс. Вспомните, что когда класс помечается как абстрактный, он может определять любое количество абстрактных членов для предоставления полиморфного интерфейса всем производным типам. Однако даже если класс действительно определяет набор абстрактных членов, он также может определять любое количество конструкторов, полей данных, неабстрактных членов (с реализацией) и т.п. С другой стороны, интерфейсы могут содержать только определения абстрактных членов.
Полиморфный интерфейс, устанавливаемый абстрактным родительским классом, обладает одним серьезным ограничением:
члены, определенные абстрактным родительским классом, поддерживаются только производными типами. Тем не менее, в крупных программных системах очень часто разрабатываются многочисленные иерархии классов, не имеющие общего родителя за исключением System.Object. Учитывая, что абстрактные члены в абстрактном базовом классе применимы только к производным типам, не существует никакого способа настройки типов в разных иерархиях на поддержку одного и того же полиморфного интерфейса.

Re: Для чего нужно разделение на class и interface?
От: Sharov Россия  
Дата: 13.12.17 17:33
Оценка:
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


Выше уже отметили -- абс. класс может иметь какое-то предопределенное поведение, а интерфейс нет. Грамотное использование абс. классов можно рассмотреть на примере паттерна Template method, когда у нас уже заложено некое желаемое поведение, и в наследниках мы можем переопределить (специфировать) поведение отдельных методов.

При проектировании классов можно пользоваться эвристикой "что" и "как". "что" -- это абс. класс, "как" -- интерфейс.
Кодом людям нужно помогать!
Re: Для чего нужно разделение на class и interface?
От: notacat  
Дата: 05.01.18 06:37
Оценка:
неплохая статья как раз про это:
Re: Для чего нужно разделение на class и interface?
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 05.01.18 21:06
Оценка:
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


Абстрактный класс и интерфейс разные понятия.

Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров.

Интерфейс (англ. interface) — программная/синтаксическая структура, определяющая отношение между объектами, которые разделяют определённое поведенческое множество и не связаны никак иначе.


Вот пример из вики по С++:
class iOpenable
{
    public:
    virtual ~iOpenable(){}

    virtual void open()=0;
    virtual void close()=0;
};


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

А в абстрактном классе достаточно создать одну чисто виртуальную функцию для подтверждения данного статуса, а там уже реализовывать какой хочешь функционал. Причём сейчас идёт разговор о парадигме объектно-ориентированного программирования. Дело в том, что интерфейс в данном случае относится к образцам проектирования (design patterns), но они как известно реализуются по-разному в каждой парадигме программирования.

К примеру, C++ является мультипарадигмальным языком программирования, а именно процедурным, функциональным, объектно-ориентированным и обобщённым. Даже в одном языке но в разных парадигмах программирования один и тот же образец проектирования реализуется одним или более способами или возможно не реализуется вовсе. Те архитекторы которые знают эту особенность могут преобразовывать программные решения основанные на образцах проектирования из одной парадигмы в другую.

А вот немного копипасты из книги Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес "Приёмы объектно-ориентированного проектирования — Паттерны проектирования" и вот как она начинается.

Предисловие

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


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

Паттерн Strategy

Название и классификация паттерна
Стратегия — паттерн поведения объектов.
Назначение
Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Стратегия позволяет изменять алгоритмы независимо от клиентов, которые ими пользуются.
Известен также под именем
Policy (политика).


Смотреть нужно не на конкретную реализацию, а на саму суть — Назначение. В процедурной парадигме программирования для подмены алгоритмов придётся использовать условные операторы, в C++ это "if..else if..else" или "switch..case..break..default". В парадигме функционального программирования того же C++ есть указатели на функции, хотя как и операторы ветвления это наследие языка Си.

А вот ++, то есть объектно-ориентированное программирование и обобщённое (шаблоные C++) дают нам новые способы реализации образца проектирования стратегия, то есть подмены алгоритмов. В объектно-ориентированном используется интерфейс стратегии и конкретные стратегии, то есть классы реализующие алгоритмы, которые и будут подменяться. Что касается обобщённого программирования, то там подмена алгоритмов классика жанра и реализуется как шаблонами классов, так и шаблонами функций. Следующая книга рекомендуемая к прочтению "Архитектура корпоративных программных приложений" Мартина Фаулера, там описаны образцы проектирования, которых нет в предыдущей упомянутой мною книге.

Но вернёмся к вопросу, почему в Java для парадигмы объектно-ориентированного программирования существует ключевое слово interface.

Интерфейс — важная конструкция для реализации объектно-ориентированного программирования в языке программирования Java.

В отличие от C++, Java не позволяет наследовать больше одного класса. В качестве альтернативы множественному наследованию существуют интерфейсы. Каждый класс в Java может реализовать любой набор интерфейсов. Порождать объекты от интерфейсов в Java нельзя. Доступно расширение одного интерфейса другим по аналогии с наследованием.

Объявление интерфейсов очень похоже на упрощённое объявление классов.

Оно начинается с заголовка. Сначала указываются модификаторы. Интерфейс может быть объявлен как public, и тогда он будет доступен для общего использования, либо модификатор доступа может не указываться, в этом случае интерфейс доступен только для типов своего пакета. Модификатор abstract для интерфейса не требуется, поскольку все интерфейсы являются абстрактными классами. Его можно указать, но делать этого не рекомендуется, чтобы не загромождать код.

Далее записывается ключевое слово interface и имя интерфейса.

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

Но это всё слова, а я вот задавался вопросом, почему в C++ нет ключевого слова interface для парадигмы объектно-ориентированного программирования, хотя в Java, C# (прочих языках дотнета) и так далее он есть. Ведь это ключевой образец проектирования и несмотря на простоту намудить при реализации в C++ можно запросто. Здесь мне думается так захотели разработчики языка.

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

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

После этого, когда в Java дают простую и понятную конструкцию, то как бы даже жаловаться особо не на что. Даже не смотря на пресловутое множественное наследование классов, такая конструкция подвержена ошибкам реализации в гораздо меньшей степени, проще для усвоения. А то ведь в том же C++ уже давно ходят шутки про реализацию виртуального деструктора и всё в таком роде.
Re: Для чего нужно разделение на class и interface?
От: vsb Казахстан  
Дата: 05.01.18 21:29
Оценка: +1
Здравствуйте, developer, Вы писали:

D>В языках программирования, например, в Java, в дополнение к типам данных (class) имеются еще и интерфейсы (interface). Почему нельзя обойтись одними только классами? Ведь есть базовый класс, есть абстрактный класс. Для чего нужно еще вводить интерфейсы?


Сложно реализовать множественное наследование классов с данными (полями). А если в классе полей нет — довольно просто. Поэтому в Java решили сделать ограничение на наследование классов с полями. А чтобы вписать это логично в язык, разделили классы на "настоящие" и на интерфейсы, в которых поля запрещены. Раньше реализации методов в интерфейсах тоже были запрещены, но это совершенно надуманное ограничение и в последних версиях в "интерфейсах" можно реализовывать и публичные и приватные методы.

Это если говорить конкретно про язык. Если говорить абстрактно, то под интерфейсом обычно понимают контракт класса, т.е. набор его публичных методов. Этот контракт можно оформлять в виде отдельного абстрактного класса (интерфейса в терминах Java) или просто иметь в виду.
Re[2]: Для чего нужно разделение на class и interface?
От: Baudolino  
Дата: 07.01.18 18:00
Оценка:
Здравствуйте, Vladek, Вы писали:

V>Интерфейс — это по сути полностью абстрактный класс

Это не так в Java 8+. Методы интерфейсов вполне могут иметь реализацию.
Re[3]: Для чего нужно разделение на class и interface?
От: Baudolino  
Дата: 07.01.18 18:03
Оценка:
Здравствуйте, developer, Вы писали:

D>Абстрактный класс то же можно сделать неизменяющимся — объявить его final.

В Java модификаторы класса abstract и final нельзя использовать одновременно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.