Интерфейс в ООП
HTML-код
- Опубликовано: 29 сен 2024
- Когда вы слышите определение интерфейса в ООП, как чего‐то, похожего на классы, но не способного реализовывать объекты, то бывает сложно понять, чем‐же это отличается от абстрактного класса. А отличие есть, и как раз об этом и пойдёт речь в этом видео‐уроке.
я нихера не понял что ты сказал. но ты мне близок. ты достучался до моего сердца
Очень вовремя, меня только что человек спросил по интерфейсам, мне лень что-то подробно объяснять, зашел на канал, и тут такой сюрприз, сразу ему скинул:) Спасибо Володь)
1:22 - это же наша верховная рада 😁 Дела задекларированы, но не реализованы))
А по видео... очень понравилось. За 10 лет нормально понял что такое интерфейсы)
Начиная с 3 минуты ничего непонятно. А нельзя было начать с простых вещей типа а зачем оно вообще нужно? Сразу два гета...ааа
Зачем так сложно. Интерфейс это просто набор сигнатур операций, без реализаций (реализация предполагается в подклассе который будет наследовать данный интерфейс). В C++ интерфейс реализуют в виде абстрактного класса, вот и всё.
Здравствуйте, хорошие видео уроки у вас, почти все все понятно) Не помешает примера использования в коде конечно. Получается, если вкратце, класс является абстрактным, если имеет хотя бы одну виртуальную функцию, а интерфейс все виртуальные и ни одной обычной.
AleksandrMyz Есть простые виртуальные а есть "полностью виртуальные", то есть совершенно не реализованые (в некоторых языках есть разница). У абстрактного минимум одна полностью виртуальная, а у интерфейса ни одной, которая таковой не является *и* нет данных.
+Vladimir Mozhenkov у абстрактного класса в Java не обязательно долны быть нереализованные методы, просто нельзя создать экземпляр этого класса и все)
Так ничего и не понял... Сколько пытаюсь понять для чего нужны интерфейсы, все без толку... (
Пожалуйста, объясните мне на примере actionscript. Есть два интерфейса и класс Alpha, который их реализует. Зачем нужны интерфейсы, если я и так могу использовать методы класса Alpha??
interface IAlpha
{
function foo(str:String):String;
}
interface IBeta
{
function bar():void;
}
class Alpha implements IAlpha, IBeta
{
public function foo(param:String):String { //тело метода }
public function bar():void { //тело метода }
}
примеду пример на псевдокоде
// интерфейсы
interface I1 { void run() }
interface I2 { void init() }
// классы реализующие интефейсы, но в теле классов данные разные
class A implements I1, I2 {
void run() { ... }
void init() { ... }
...
}
class B implements I1, I2 {
// тут такая же реализация
... }
..
class N implements I1, I2 {
// тут такая же реализация, ну еще могут быть свои методы :-)
... }
class service_init {
void static initialize(I1 ob) { ob->init(); }
}
class service_run() {
void static execute(I2 ob) { ob->run() }
}
// едем дальше
// создаем коллекцию объектов
A a; B b; C c; .... N n;
I1 init_array = {a, b, c, ..., n}
I2 exec_array = {a, b, c, ..., n};
foreach (init_array as item) { service_init::initialize(item); }
foreach (exec_array as item) { service_run::execute(item); }
двум сервисным классам неважно какого типа классы, но важно какой реализован интерфес.
это как раз нужно для взаимозаменяемости объектов. один интерфейс и множество реализаций -- то есть полиморфизм. ну и решения задачи множественного наследования.
реализация интерфейса в си++ выглядит так же как наследование?
по грамматике
спасибо!!! все понятно
Владимир, у Вас пэйпал есть? Хочу поддержать проект но других виртуальных денег нет.
+Nikita Mader Да. Он даже в описании канала стоит: Volodya@whengendarmesleeps.org
+Nikita Mader P.S. Заранее благодарю )))
На собеседовании часто спрашивают зачем использовать интерфейсы если нужные методы можно просто написать вручную. Как бы вы ответили на этот вопрос?
В интерфейсе просто описаны методы без реализации, а в классах которые имплементируют этот интерфейс идет реальная их реализация, и классов, которые имплементируют интерфейс может быть много, и не надо для каждого писать свой метод, т.е. для оптимизации и порядка
@@suss9185 В интерфейсах есть дефолтные методы,в которых можно указать реализацию
@@vsevolodtsukanov7917 но ведь раньше не было и все равно их использовали. интерфейсы нужны по большей части для чистоты и порядка, а также ты всегда будешь понимать, что объект может делать просто взглянув на интерфейсы, которые он реализует
Довольно хорошее объяснение, простое, но как по мне, то лучше объяснять интерфейсы как некоторые контракты. Это подобно тому, как человек заключает констракт с фирмой, и обязуется по этому контракту выполнять какие-то функции (как специалист этой фирмы). Также и с интерфейсами в ЯП. То есть по сути, это список того, что должен делать объект. Но в этом списке не указывается, как нужно это выполнять. Доступим есть интерфейс flyable, в котором есть метод fly(). Этот интерфейс указывает на то, что объект, реализующий этот интерфейс, может летать. Но там не сказать, как он это будет делать. И это неважно. Это похоже на некоторые роли или функциональные обязанности.
Тут я могу привести пример с гонками или бегами, например. То есть допустим, проводятся соревнования по тому, кто быстрее достигнет какой-то точки. У всех объектов, которые будут участвовать в этой гонке, есть метод move() - двигаться, но, допустим, это будут совсем разные объекты (например, соревнование среди инопланетян, которые все двигаются по-разному). В итоге, при старте ты всем даёшь команду move (вызываешь этот метод), и все начинают двигаться. В программе это можно сделать так: кто-то двигается точно по прямой, кто-то змейкой, кто-то двигается то ускоряясь, то замедляясь, кто-то - равномерно, кто-то - с постоянным ускорением, и т.д....
Все верно, большинство сказанного относится и к виртуальным функциям. У папы есть виртуальный метод fly() , а каждый потомок реализовывает его по разному.
спасибо большое, спасли меня, я так и не смог понять окончательно, пока не увидел ваш комментарий
Лучше объяснять интерфейсы на реальном приложении , А эти твои вымыслы фантазии такое же Ни о чем что и само видео 🤮🤮🤮
Объясняешь как будто для тех, кто уже в курсе что такое интерфейс. Лично я нихуя не понял. Озвученное вначале определение это наименьшее, что меня запутало. Оно не идет ни в какое сравнение по запутанности с тем, что я услышал дальше. Объяснять нужно так, чтобы самый дальний от программирования человек на земле тебя понял, чтобы даже кассирша из магнита сказала: "ну епрст я терь штоли пограмистка ха? людк ты слышала а? я терь знаю шо за интерфейсы такие от хохма то!". Двойка тебе.
Правильно ли я понимаю что интерфейс, это некая "рекомендация" разработчикам реализовать определенные методы, что бы они не забыли их реализовать и придерживались неких оговоренных стандартов в проекте, так сказать. Ну например группа разработчиков. каждый делает свой класс, "главный архитектор" специально вводит интерфейс с декларацией определенных методов и в ТЗ дает указание его добавить в свой класс определенным разработчикам, что бы те точно реализовали в своих классах строго определенные методы, т.к. другие разработчики пишут другие классы которые по этим строго определенным в ТЗ методам будут обращаться к экземплярам класса.
Dmitry O в принципе так и есть) Разработчики должны придерживаться стандартов. Методы должны быть названы определенным образом. Далее разработчик реализует эти методы в классе
итог: Интерфейсы нахер не нужны (Если только в огромных планированных проектах). Только больше путаницы из-за них в ООП
вроде что то понимал... А теперь ещё больше запутался... Для чего он нужен?! Изобретение велосипеда усложняющего жизнь?
Ну и как обучение спустя 4 года?
@@anatolylushnikov3315 Круто! 3 года как frontend разработчиком работаю. Дорогу осилит идущий ))
upd. И да. Мне 40 лет.
Афигеть, оказывается можно объяснить нормально человеческим языком, когда человек хочет.
Спасибо Владимир! Из всего что нашел, это самое лучшее описание этого приема!
Я думаю что если проецировать на реальный мир интерфейсы и раскрыть всю суть множественного наследования хорошим примером является это:
Предположим у нас есть птичка, самолет и машина. Птичка может летать и бегать, самолет может летать и ездить, а машина может только ездить. У всех трех сущностей есть какие-то общие черты. Птичка и самолет летает, самолет и машина ездит. А значит, птичка реализует интерфейсы "летающий" и "бегающий", самолет реализует интерфейсы "летающий" и "ездящий", а машина реализует интерфейс "ездящий". По итогу, мы можем абстрагироваться от сущностей и работать с ездящими, летающими, и бегающими не задумываясь о том кто они по природе своей. Абстрактный класс нам не предоставляет такого функционала. Да, мы можем создать абстракцию для летающих и бегающий, но унаследоваться от обеих не можем. Абстрактный класс требует реализовать какой-то метод, а интерфейс, говорит о том что такой метод есть. Это некая гарантия того, что объект будет иметь некий функционал. Как в народе говорят, мы заключаем контракт с методом, и гарантируем что у входящего параметра метода есть определенный функционал. Именно поэтому интерфейсы еще называют контрактами.
Вот я правильно понял, глаголы (т.е. функции которые что то делают), лучше реализовать интерфейсами?
к примеру GetNubmer();
Я нихуя не поняль. Спасибо.
Интерфейс довольно таки коварная тема. И его просто неопрятными рисунками на доске(без обид я не принижаю твой труд) не доведешь до человека. Сделай пожалуйста видео с примерами на редакторе так понятнее будет думаю
П.С. не сразу увидел что видео 6 летней давности. И все таки)
Володя, описанный вами пример касательно Serializable для Java не применим, т.к. в Java этот интерфейс является флаговым и не имеет методов для реализации. Т.е. JVM сама генирирует байт-поток всех объектов, вложенных в класс, с implements Serializable.
Александр Айронз Этого не знал, благодарю.
В Джаве вообще довольно много интерфейсов-маркеров, нужно это иметь в виду.
Интерфейс не содержит состояний, в отличии от абстрактного класса. 🎉
Володя Володя, не верь погоде, не верь туманам и дождям..
class - .cpp
interface - .h
После изучения основных вопросов по с++, с удовольствием посмотрю уроки по ассемблеру, если конечно таковые планируются.
AleksandrMyz поюсую, очень интересная тема.
Чел, да ты больной.
@@Inflactwf неожиданно, спустя 5 лет)
@@VoidCitizenSounds надеюсь ты уже пропил таблеточки против Ассемблера, иначе процесс необратим =)
@@Inflactwf А в чем дело? Ассемблер вполне нужен при реверс-инжиниринге кода, например. А то, что успели добавить в современных процессорах и подумать страшно, мало информации по этой теме.
Спасибо, Владимир! Ты меня натолкнул на мысль посмотреть как интерфейсы реализованы в С++, и все стало понятно! Получается в С# интерфейсы нужны для реализации множественного наследования от абстрактных классов. Костыль такой))
Спасибо, интересно
Как интерфейс помогает с решением проблем множественного наследования?
Допустим базовый класс "техника". От него наследуется классы "машина" и "самолет". Оба этих класса используются для создания объектов.
Далее нужно сделать класс "летающая машина", унаследовавши элементы и машины, и самолета.
Если вместо наследования, допустим, самолета, наследовать интерфейс, то придется копировать весь код класса самолет в класс "летающая машина" - так себе помощь.
07:11 Смысл понятен, но пушинки не летают =)
Как говорила главная героиня в Kara no Kyoukai:
- Ты летаешь или паришь?
Благодаря твоему комменту посмотрел первый эпизод. Необычно, мне понравилось.
Я пытаюсь понять про Interface segregation principle - по этому принципу задача выглядит так, что вот есть класс с кучей методов и есть несколько клиентов каждому из которых нужны лишь несколько из этих методов. И я не понимаю - как интерфейсы в описанном виде "выдернут" из класса нужные методы.
могут ли интерфейсы хранить переменные?
Чистый - нет, грязный - да 😀
Самое понятное объяснение данной темы из всех, что я видел 👍
борода двуслойная :)
Второй слой, просто наследуется от первого) Ниче вы не понимаете в ООП)
Я думаю интерфейсы нужны не для того, чтобы решить проблему множественного наследования, интерфейсы нужны для связи разных уровней абстракции, согласно 5 принципу SOLID. Допустим, у нас программа, работающая с БД, и у нас есть два слоя: Сервис и Репозиторий. Сервисный слой может работать с любым типом БД, а репозиторий уже на низовом уровне реализует работу с конкретной БД. Соответственно, чтобы связать два этих слоя, мы в сервис должны передать ссылку на созданный репозиторий. Но при проектировании класса, мы в соответствии с пятым правилом SOLID указываем, что принимаемый репозиторий должен реализовать определенный интерфейс, а не указываем его соответствие конкретному классу, так как на данном уровне абстракции мы не знаем о них. Мы лишь знаем, какие методы нам нужны. Таким образом слой высокого уровня не зависит от слоя низкого уровня. Интерфейсы реализуются на уровне более высокого слоя, в то время как абстрактные классы реализуются непосредственно на том уровне, где от него наследуются уже непосредственно конкретные классы-реализации
Невозможно сосредоточиться, только что и могу, так это смотреть на бороду)
Nikita Sharaev А волосы не ебет?
а усы, которые так смешно свисают ?
Не плохая телретическая выкладка. И так понимал, но благодарю за дополнительные образовательные данные.
все пишут про бороду, но меня коробит от того, что он пишет маленькую е как большую Е, в get - вот от этого мне плохо, принесите корвалола пожалуйста!
Наконец-то обьяснение для людей, а не сухие термины "бла-бла". Спасибо
В Java есть множественное наследование там нет интерфейсов?
Все эти уроки хороши, но не помешали бы примеры реализации этих штук в конкретном языке (было бы ещё понятнее, а то так по сути - это просто теоретизирование)
Думаю стоило упомянуть, что можно создавать разные реализации под интерфейсы обязующие реализовать одинаковый метод. То есть под каждый интерфейс своя реализация, в таком случае вызвать эту функцию не самого класса нельзя (* по крайней мере в С# так).
А видео очень годные делаешь, спасибо. Интерфейс очень доступно объяснил.
Удивительно, так просто и понятно объяснил, что стало интересно
спастбо
Спасибо. Класс - интерфейс "на стероидах", в плане, как нормальный человек (интерфейс) и бодибилдер (класс). А между ними спортсмен (абстрактный класс), по объему и реализуемому функционалу.
С Java 8 есть default методы, которые могут, для совместимости, содержать реализации, которые мы затем переопределяем в классах-реализацииях (abstract / superclass, subclass).
большей ереси я ещё не слышал
Пока сам не упрусь в необходимость это использовать не пойму, но пока обхожусь без этого видимо)
Правильно. Это нужно далеко не всегда. Интерфейсы нужны для связывания классов между собой. Как это обычно делается? Классу А передаётся ссылка на класс В. А потом этот класс А вызывает у класса В какой-то там метод ToDo(). И вроде бы всё прекрасно.
class A
{
public void Func(B b)
{
b.ToDo();
}
}
class B
{
public ToDo();
}
Но как быть, когда возникает потребность вызывать этот метод ToDo() не только у класса В, но и у класса С? Как вы передадите по ссылке оба класса сразу? Это хорошо, если у класса В и С есть общий предок. Тогда можно указать на него. Ну а если общего предка нет, тогда как?
И тут приходит на помощь интерфейс. Вы указываете в интерфейсе метод, который должен вызываться классом А, а потом заставляете классы В и С реализовать этот интерфейс. Далее класс А будет получать ссылку. Только теперь уже не на какой-то класс, а на интерфейс.
interface ISample
{
void ToDo();
}
class B : ISample
{
public ToDo();
}
class C : ISample
{
public ToDo();
}
class A
{
public void Func(ISample sample)
{
sample.ToDo();
}
}
Таким образом, мы отвязываем класс А от жёсткой связи с каким-то определённым классом. И если у вас этот класс А находится в некой библиотеке, то может даже получиться так, что ему будет передаваться через интерфейс клиентский класс, написанный через 10 лет после создания библиотеки! И всё будет прекрасно работать, что даже библиотеку не придётся переделывать.
круто и понятно объясняете!
Большое спасибо, очень доходчиво!
11:47 автор ролика оговорился: в С нет интерфейса.
Понятно что ничего не понятно
Nakonecto ))) podpiska +like
"Кому же это нужно было, чтобы создать это" - напомнило "Если звёзды светят, значит это кому-то нужно" (С) Маяковский
Спасибо!
Все равно немного непонятно. В видео вы приводите пример, что интерфейсы понадобились для разрешения конфликтов именно при множественном наследовании. Но эти интерфейсы есть в языках программирования, где нет множественного наследования. Если брать тот же PHP, там нет такой возможности, но есть интерфейсы. Тогда становится непонятно какая будет разница между использования обычного абстрактного класса и интерфейса в этом случае? Точно так же можно создать абстрактный класс и продекларировать там все методы, которые нужно реализовать в дочерних.
+Андрей Сафиуллин "Но эти интерфейсы есть в языках программирования, где нет множественного наследования." Да. То есть они дают возможность сделать тоже, что позволяет делать множественное наследование, но без возможных проблем множественного наследования.
В C++ программист сам должен убедиться, что проблем нет. В Java проблем быть никогда не может в принципе.
А что с языками у которых и классов нет, т.е. и наследовать нечего? Напр. Go?
class A
{
public:
virtual void f()=0;
};
class B
{
virtual void f()
{
printf("vv");
}
};
class C: public A, public B
{
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
C c;
c.f();
return a.exec();
}
Код, відповідний вашій діаграмі, не компілюється
используйте виртуальное наследование.
class B : public virtual A {...};
class C: virtual public A, virtual public B {...};
Умный Негр А в чем проблема?
По моему лучше в редакторе это показывать, а не на доске каракулями. Мешает восприятию