Только начинаю касаться ООП.
Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный.
Везде какой то бред написан, нихрена не пойму.
Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
Здравствуйте, Zender, Вы писали:
Z>Только начинаю касаться ООП. Z>Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный. Z>Везде какой то бред написан, нихрена не пойму. Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
Здравствуйте, Zender, Вы писали:
Z>Только начинаю касаться ООП. Z>Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный. Z>Везде какой то бред написан, нихрена не пойму. Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
Здравствуйте, Zender, Вы писали:
Z>Только начинаю касаться ООП. Z>Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный. Z>Везде какой то бред написан, нихрена не пойму. Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
ООП без полиморфизма невозможно. Без полиморфизма это тупо С с классами.
Класс [Животное]
{
virtual срать() = 0;
}
Класс [Лошадь] : [Животное]
{
virtual срать()
{
поднять_хвост();
навалить_яблок();
}
}
Класс [Собака] : [Животное]
{
virtual срать()
{
присесть();
навалить();
}
}
Класс [Ферма]
{
//Список зверей на ферме
std::list<Животное *> звери;
//Конструктор фермы
Ферма()
{
//Добавляем зверей
звери.append(new Лошадь());
звери.append(new Собака());
}
//все срём по рассписаниюvoid дефекация()
{
for_each(Животное * зверь, звери)
{
зверь->срать();
//Каждое животное будет срать по своему
//Обрати внимание что в списке у нас Животное
//а добавляем мы конкретных зверей
//но срать заставляем через указатель на Животное
//это и есть полиморфизм
}
}
}
Простейший пример из алгоритмов, вводим некий интерфейс comparable который только устанавливает между объектами некое свойство "старшинства"
bool Icomparable::isGreater(Icomparable& lh);
Теперь мы можем написать большое множество алгоритмов сортировки , операций над множествами и т.п. используя этот интерфейс (контракт).
Теперь любой объект который реализует этот интерфейс может пользоваться алгоритмами реализованными для этой операции.
Например строка с учетом заглавных букв и без учета , действительные числа с учетом знака и без учета, животный мир по к-ву ног или глаз, эксперты по уровню квалификации и т.п.
Здравствуйте, Zender, Вы писали:
Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
из документации по функции addWidget класса QLayout
Или QIODevice, где можно написать алгоритм на его методах. Потом создать объекты QFile, QBuffer и QTcpSocket, и через динамическое приведение типов передать их этому алгоритму. Алгоритм закодирован один раз, но благодаря полиморфизму может работать с разными источниками данных. Аналогичных полиморфизму (объектно-ориентированное программирование) результатов в C++ можно добиться с помощью шаблонов C++ (обобщённое программирование), так поступают в stl и boost. Тоже самое касается Java, C# и других.
Z>Только начинаю касаться ООП. Z>Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный. Z>Везде какой то бред написан, нихрена не пойму. Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
Это возможность выполнять одну и ту же операцию над разными данными:
print( 10 ); // <= операция print выполняется над числом.
print( "опа" ); // <= операция print выполняется над строкой.
// Полиморфизм, однако.
Полиморфизм в целом бывает signature based — когда задаются несколько пераций с одним именем, принимающие разные данные. А еще бывает capability based — это когда сами данные предоставляют некий одинаковый интерфейс, чтобы с ними могла работать одна операция. Еще полиморфизм бывае времени выполнения и вреени компиляции. Полиморфизму сильно помогают фияи, реализованные в языках программирования — перегрузка функций/методов, интерфейсы, шаблоны. Но в целом можно обойтись и без них, просто кода становится несколько больше.
В целом полиморфизм почему-то сильно связывают с ООП, но на мой профессиональный взгляд это все же разные штуки.
Здравствуйте, CannyMan, Вы писали:
CM>Здравствуйте, Eye of Hell, Вы писали: EOH>>Это возможность выполнять одну и ту же операцию над разными данными: EOH>>
EOH>>print( 10 ); // <= операция print выполняется над числом.
EOH>>print( "опа" ); // <= операция print выполняется над строкой.
EOH>>// Полиморфизм, однако.
EOH>>
CM>Какой же тут полиморфизм. Банальная перегрузка функций.
Банальная перегрузка функций есть ad-hoc полиморфизм
Здравствуйте, samius, Вы писали:
S>Здравствуйте, CannyMan, Вы писали:
CM>>Здравствуйте, Eye of Hell, Вы писали: EOH>>>Это возможность выполнять одну и ту же операцию над разными данными: EOH>>>
EOH>>>print( 10 ); // <= операция print выполняется над числом.
EOH>>>print( "опа" ); // <= операция print выполняется над строкой.
EOH>>>// Полиморфизм, однако.
EOH>>>
CM>>Какой же тут полиморфизм. Банальная перегрузка функций. S>Банальная перегрузка функций есть ad-hoc полиморфизм
Вы путаете overloading и overriding. Полиморфизм это overriding. А в этом случае overloading.
Здравствуйте, CannyMan, Вы писали:
CM>>>Какой же тут полиморфизм. Банальная перегрузка функций. S>>Банальная перегрузка функций есть ad-hoc полиморфизм CM>Вы путаете overloading и overriding. Полиморфизм это overriding. А в этом случае overloading.
Никто ничего не путает. Полиморфизм бывает разный. Когда мы пишем List<T> — это тоже вполне себе полиморфизм, только уже параметрический. Полиморфизм — это очень общее понятие, и не надо его путать с dynamic binding, который попросту один из механизмов реализации.
Здравствуйте, CannyMan, Вы писали:
CM>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, CannyMan, Вы писали:
CM>>>Какой же тут полиморфизм. Банальная перегрузка функций. S>>Банальная перегрузка функций есть ad-hoc полиморфизм CM>Вы путаете overloading и overriding. Полиморфизм это overriding. А в этом случае overloading.
Здравствуйте, Zender, Вы писали:
Z>Только начинаю касаться ООП. Z>Подскажите, а что такое Полиморфизм. Ну вообще не догоняю. Если лучше на примере, можно и пример, просто и примитивный. Z>Везде какой то бред написан, нихрена не пойму. Z>Вот что такое Инкапсуляция, Наследование — это понятно. Это я вижу где приминить можно, где воспользоваться и т.д. А вот Полиморфизм вообще никуда не упирается.
А вот нам прямо сегодня на курсе тренер из Л******* объяснил: "это когда мы можем подсунуть, а он смимикрирует".
Здравствуйте, Eye of Hell, Вы писали:
CM>>Какой же тут полиморфизм. Банальная перегрузка функций.
EOH>Увы, но по имеющейся у меня информации перегрузка функций — это один из самых банальных способов реализации полиморфизма.
Ага, и как ваш код из DLL будет банально перегружать функции классов которых еще нету на момент компиляции DLL-ки?
Дворник Василий вам информацию задарма скинул?
Ну тогда уже Двойная диспетчеризация вообще никому никогда не понадобится, разве что перед Девками хвастаться здесь
EOH>>Увы, но по имеющейся у меня информации перегрузка функций — это один из самых банальных способов реализации полиморфизма. V>Ага, и как ваш код из DLL будет банально перегружать функции классов которых еще нету на момент компиляции DLL-ки?
Не понял вашего вопроса. При чем тут перегрузка методов классов, код которых недоступен на момент компиляци? Если код на момент компиляции недоступен — то средствами языка с static binding оно не перегружается. Для таких вещей другие конструкции придумали — тот же COM, например.
Здравствуйте, Vaako, Вы писали:
V>Здравствуйте, Eye of Hell, Вы писали:
CM>>>Какой же тут полиморфизм. Банальная перегрузка функций.
EOH>>Увы, но по имеющейся у меня информации перегрузка функций — это один из самых банальных способов реализации полиморфизма.
V>Ага, и как ваш код из DLL будет банально перегружать функции классов которых еще нету на момент компиляции DLL-ки? V>Дворник Василий вам информацию задарма скинул? V>Ну тогда уже Двойная диспетчеризация вообще никому никогда не понадобится, разве что перед Девками хвастаться V>здесь
Вы хотите дискредитировать саму информацию, ее источник, или свою способность к анализу и осмыслению информации?
Здравствуйте, Vaako, Вы писали:
V>Ага, и как ваш код из DLL будет банально перегружать функции классов которых еще нету на момент компиляции DLL-ки?
Полиморфизм бывает статический — работающий на этапе компиляции, и динамическим. Перегрузка вид статического полиморфизма. Шаблоны С++ и перегрузка так же обеспечивают статический полиморфизм.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Vaako, Вы писали:
V>>Ага, и как ваш код из DLL будет банально перегружать функции классов которых еще нету на момент компиляции DLL-ки?
VD>Полиморфизм бывает статический — работающий на этапе компиляции, и динамическим. Перегрузка вид статического полиморфизма. Шаблоны С++ и перегрузка так же обеспечивают статический полиморфизм.
Я так плохо разбираюсь в таких вещах, что надо погуглить:
Перегрузка функций это специальная техника, позволяющая создавать несколько функций с одинаковыми именами в одной области имен. При этом функции должны отличаться т.н. сигнатурой функции.(1)
В процессе компиляции C++ принимает во внимание количество аргументов, используемых каждой функцией, и затем вызывает именно требуемую функцию. Предоставление компилятору выбора среди нескольких функций называется перегрузкой.
Полиморфизмом в программировании называется переопределение наследником функций-членов базового класса. Какая именно из функций будет вызвана определяется во время компиляции.
class Figure
{
...
void Draw() const;
};
class Circle : public Figure
{
...
void Draw() const;
};
Circle *c = new Circle(0,0,5);
Figure *f = c; // Всё ok: Figure — базовый класс для Circle
c->Draw();
f->Draw();
// Указатели друг другу равны, но для f будет вызвана другая функция, чем для c
Несмотря на то, что оба указателя указывают на один и тот же объект класса Circle, для c будет вызвана Circle::Draw(), а для f — Figure::Draw(), поскольку f — указатель на объект класса Figure. Такой полиморфизм называется статическим. (2)
Но в C++ есть и динамический полиморфизм, когда вызываемая функция определяется во время выполнения. Для этого функции-члены базового класса должны быть объявлены виртуальными.(3)
(*) Ага, значит при перегрузке множество функций из которых компилятор выбирает должны отличатся сигнатурой. Неявный параметр (this, self и т.д.) к сигнатуре не относится. Статический полиморфизм this также не использует(2).
(**) При полиморфизме сигнатуры должны совпадать? Вроде должны.
(***) Перегрузка кроме сравнения сигнатур перебирает все явные и неявные преобразования типов. Это значит, что код может перестать компилироваться, если возникнут неопределенности с преобразованиями типов (ambiguous call to overloaded function). Не уверен что при статическом полиморфизме возможна неоднозначность в выборе нужной функции.
Потому действительно если нет желания различать эти два механизма, то можно путать их между собой. Хотя при двойной диспетчеризации нужно использовать и перегрузку и полиморфизм. Хотя постойте, можно ведь все функции переделать добавив два новых аргумента foo(A* thisA, B* thisB, …. ).
Уря у меня получилось простой перегрузкой охватить и динамический полиморфизм и двойную диспетчеризацию. Думаю если постараться то можно и множественное наследование свести до перегрузки функций. Так можно все что угодно свести к перегрузке.