ООП: Чи є overloading поліморфізмом?

Всім привіт,
Кілька днів тому в одному з відеокурсів почув інформацію про те що overloading (перегрузка) методів не є поліморфізмом. Автор дає визначення «Це виконання однієї команди з різними параметрами. Тому overloading не є поліморфізмом». Але як так? В університеті, на вікіпедії, та майже скрізь вказано що overloading це поліморфізм (в деяких джерелах вказано що це Ad-hoc). Що ви думаєте на рахунок цього? Оverloading це поліморфізм чи ні?

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Многа букав.

Есть такая штука как динамическая диспетчеризация (dynamic dispatch). Она бывает single и multiple.

Single dynamic dispatch позволяет выбирать метод/функцию в рантайме в зависимости от типа одного параметра.

Multiple dynamic dispatch позволяет выбирать метод/функцию в рантайме в зависимости от 2 и больше параметров.

Динамический полиморфизм (Вы скорее всего имеете в виду именно его, есть еще статический) это single dynamic dispatch в котором первый параметр предоставляет информацию о типе (this, self). В зависимости от типа вызывается свой метод. Понятно, что в разных языках это реализуется по-разному, но суть остается той же.

В Лиспе (CL, Clojure), например, есть поддержка multiple dynamic dispatch через т.н. мультиметоды (пример взят отсюда clojure.org/...bout/runtime_polymorphism ):

(defmulti encounter (fn [x y] [(:Species x) (:Species y)]))

(defmethod encounter [:Bunny :Lion] [b l] :run-away)
(defmethod encounter [:Lion :Bunny] [l b] :eat)
(defmethod encounter [:Lion :Lion] [l1 l2] :fight)
(defmethod encounter [:Bunny :Bunny] [b1 b2] :mate)

(def b1 {:Species :Bunny :other :stuff})
(def b2 {:Species :Bunny :other :stuff})
(def l1 {:Species :Lion :other :stuff})
(def l2 {:Species :Lion :other :stuff})

(encounter b1 b2)
-> :mate
(encounter b1 l1)
-> :run-away
(encounter l1 b1)
-> :eat
(encounter l1 l2)
-> :fight

Если с Clojure не знакомы, то пример выглядит, мягко говоря, странно :) Давайте разберем его по шагам, не обращая внимание на «дикий» синтаксис.

Multiple dynamic dispatch работает так: мы определяем функцию, которая будет «выбирать» кого вызвать в зависимости от параметра — т.н. dispatch function. В примере выше мы говорим, что определяем мультиметод, который называется encounter,

(defmulti encounter ,,, )

а его dispatch-функция это лямбда:

(fn [x y] [(:Species x) (:Species y)])

которая принимает два параметра х и у и возвращает массив из двух значений. Вот это (:Species x) значит, что мы из х по ключу «:Species» вытаскиваем значение (т.е. х и у это maps).

Дальше мы определяем наши методы:

(defmethod encounter [:Bunny :Lion] [b l] :run-away)

defmethod принимает имя метода (encounter), потом параметр по которому мы делаем выборку/диспетчеризацию (массив двух значений [:Bunny :Lion]), затем список параметров метода ([b l]), затем тело метода (в данном случае он просто возвращает одно значение — :run-away). Так вот если посмотреть на параметры, по которым идет диспечеризация:

Вот это создает «переменные» с именем b1, b2, l1, l2, которые являются map-ми:

(def b1 {:Species :Bunny :other :stuff})
(def b2 {:Species :Bunny :other :stuff})
(def l1 {:Species :Lion :other :stuff})
(def l2 {:Species :Lion :other :stuff})

Теперь пробуем вызвать метод:

(encounter b1 b2)

Здесь выведется :mate, т.е. будет вызван метод (defmethod encounter [:Bunny :Bunny] [b1 b2] :mate). Как это происходит. Сначала вызывается функция, которая выполняет диспетчеризацию. Как мы помним, она вытаскивает из обоих map то, что лежит в них по ключу :Species. В нашем случае она вернет [:Bunny :Bunny]. Это значение используется для вызова функции: (encounter [:Bunny :Bunny] b1 l1). Кложур смотрит, есть ли метод с такой «сигнатурой» и если есть, то вызывает его. В нашем случае он таки есть :)

Так вот, к чему это все. Все что я описал выше, это то, что происходит в рантайме. В компайл-тайме подобные операции может делать компилятор. Более того, он не только может, но и делает для function overloading: в зависимости от типов параметров, он подставляет соответствующую функцию. Это тоже диспатч, это тоже полиморфизм. Только не динамический, а статический :)

ОДМИНЫ: Добавьте плз нормальную тулбарину для форматирования текста. А лучше прикрутите аски-док или на худой конец маркдаун :О)

Ще одне питання: Перекриття(Hidding) методів це поліморфізм?

Дізнатися б, що таке hidding... :)

Створення таких самих методів як у базовому класі але без слова override

Ok, thanks! Пішов вивчати питання...

ну переопределил у дочернего класса статический метод, какой тут полиморфизм? тут уже даже с точки зрения семантики не приколупаешься.

погоджуюся з Вами, але на MSDN в статті про поліморфізм розказується про Hiding Base Class Members. msdn.microsoft.com/...-ru/library/ms173152.aspx

ну судя по примеру

DerivedClass B = new DerivedClass();
B.DoWork(); 

BaseClass A = (BaseClass)B;
A.DoWork(); 
это не скрытие

хотя мне сокрытие знакомо только из мира джавы, может у шарпа другое понимание

Не розумію, чому це питання викликає якісь сумніви, бачу купу суперечок. Наприклад питання — «Гірськолижний спорт: чи можна слаломом спуститись з гірки», напевне, не буде викликати жодних сумнівів. Поліморфізм — це абстрактне поняття, яке, на мою думку, передбачає зміну поведінки в залежності від середовища. ООП — це підхід до проектування ПЗ, яке базується на поліморфізмі. Overloading — буде поліморфізмом чи в ООП, чи поза ним. Взагалі як на мене, набагато простіше доказати, що щось є поліморфізмом, ніж це заперечити. Якщо поліморфізм підтримується на рівні мови — це супер, але що вам забороняє вигадати свій спосіб поліморфізму. Якщо у вас у коді є хоча би один if, switch чи for — ваша програма вже певною мірою якась поліморфна.

Справа в тому, що сама парадігма ООП базується на трьох принципах: поліморфізм, спадкування та інкапсуляція. І ось саме цей поліморфізм передбачає цілком конкретні ознаки (їх ми тут уже обговорили багато разів). Те, що є поліморфним і поза контекстом ООП, не є тим поліморфізмом, про який ідеться в контексті ООП.

Я чомусь завжди думав, що ООП базується «тільки» на поліморфізмі, дякую що розяснили. Також дякую вам за те, що пояснили, що термін поліморфізм, в ООП треба трактувати тільки так, як він реалізований в мовах програмування.

Ось ви знущаєтесь, а я ж не казав, що цей принцип в ООП треба трактувати так, як його реализовано в мовах програмування, це вже ви домислили.
По-друге, акцент був не на тому, що ООП базується на чомусь іще, а на тому, що поліморфізм в контексті ООП це не те ж саме, що поліморфізм поза його контекстом.

Перепрошую, що це виглядало для вас як знущання. Це я намагався жартувати, тому що, нажаль, не вірю що у нас вийде якась конструктивна дискусія, але зроблю ще останню спробу. Якщо би автор задав питання, чи є overloading способом реалізації поліморфного поводження обєктів в ООП під час рантайм — відповідь була би — категорично ні. Але автор задав досить нечітке питання, чи є overloading поліморфізмом в ООП, тут вже не раз говорили, що overloading — це Ad-hoc поліморфізм, для вас до компіляції, виглядає що метод обєкту до якого ви бидете звертатись під час виконання програми має поліморфні властивості, тому однозначна відповідь — так, є поліморфізмом в ООП. Щоб це зрозуміти, визначіть для себе значення терміну поліморфізм, взагалі, без ООП. Потім вже розумійте яку роль він відіграє в ООП, потім розрізніть собі період до компіляції, та після (я вважаю що ООП включає два, і перший, звісно, головний), і я впевнений що не буде жодних сумнівів.

У той же час якась мова може не відповідати другому, але завжди має відповідати першому принципу поліморфізму (я маю на увазі поліморфізм об’єкта), щоб належати до об’єктно-орієнтованих мов.

кто-нибудь, лучше расскажите как эти знания помогает кому-то на практике)
ну, в смысле, вот вы знаете что «так делать можно», и «вот так тоже можно», «а вот так нельзя, не поддерживается» — и комбинируете подходы по мере надобности. какой практический толк от знания точного определения?

А это как паттерны проектирования. Программируешь такой лет 15 уже, и вдруг узнаешь, что вот это хреновина, которую в каждом проекте по сто раз используешь, оказывается никакая не хреновина, а, прости господи, абстрактная фабрика! А другая фиговина, ёханный бабай, — синглтон! И рассказывает тебе об этом студент четвертого курса, который не знает, чем присвоение строки отличается от присвоения динамического массива.

:) Это ж где Вы 15 лет назад использовали что-либо на абстрактную фабрику похожее? Или, прости господи, синглотон?

15 лет назад — это всего-то 2001 год. Использовали в C++ Builder, Delphi.

И где в делфи или буилдере вы использовали абстрактную фабрику? Мною написано много реально работающего софта на еще Delphi 5, кое что и сейчас наверное работает, но без фабрик. Фабрики быстро понадобились когда коснулся джава

Вами написано без фабрик, наша команда писала с фабриками. За давностью лет не упомню, это было в проектах из банковской системы, в паре учетных систем. Параллельная команда писала на Java, делились опытом, внедряли лучшие практики так сказать.

О, не думал, что уже в 2000 году были серьезные проекты на джаве. Посыпаю голову пеплом.

И где в делфи или буилдере вы использовали абстрактную фабрику?
А чем в этом плане один ООП-язык отличается от другого ООП-языка?
.
Конкретно на Delphi при помощи слегка упрощенной «абстрактной фабрики», например, реализовывался уровень абстракции от СУБД. Какой-нибудь TConnection.CreateQuery создает для ситуативного выполнения запросов временный объект типа TQuery, а экземпляром чего оный в данной ситуации является, TOracleQuery(TQuery) или TMsSQLQuery(TQuery), — не важно.
.
А когда началось широкое использование COM и интерфейсов, то вообще пошло-поехало!
.
Что касается синглтона, то глобальный объект Application именно им всю жизнь и являлся.

Application и действительно сингл, спасибо.

Странно это слышать от разработчика с вашим стажем :)

Не странно. 15 лет назад это было не странно

В общем случае согласен, кому с чем приходилось работать на тот момент. Видимо, сказалось мое довольно раннее знакомство с Джавой.

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

На практиці розуміння таких принципів допомагає не писати

if (dog typeof SlimDog) {
    dog.setCollar(new NarrowCollar());
} else if (dog typeof FatDog) {
    dog.setCollar(new WideCollar());
} else {
    throw new IllegalArgumentException("Unknown type " + dog.getClass());
}
там, де можна написати
dog.chooseCollar();

є,
тільки тре розрізняти поліморфізм на рівні компіляції і поліморфізм в момент виконання програми

Хороший философский вопрос, как и обсуждение вышло.
Примерно как в недавнем посте у Болдачева о совпадающих смыслах, на примере «стол» и «ящик».
ООП ж не математика. Отсюда и определения не раскрывающие смыслы. И не выводимые из аксиом, с помощью однозначных правил

Я тут вже вказали — це Ad hoc polymorphism. Терміну вже майже 50 років
en.wikipedia.org/wiki/Ad_hoc_polymorphism
На цьому питання можна закрити.

Як тут уже сказали, це створення нового метода, а не виклик заданого, тож це не поліморфізм. Питання можна закрити.

In programming languages, ad hoc polymorphism is a kind of polymorphism in which polymorphic functions can be applied to arguments of different types, because a polymorphic function can denote a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied.
ООП
Автро питає про поліморфізм в ООП, ане в функціональному програмуванні.

З якого це часу Smalltalk, який згадується в статті, перестав бути ООП мовою і перетворився на функціональну мову?

Smalltalk is an object-oriented, dynamically typed, reflective programming language.
In Smalltalk, the overloading is done at run time, as the methods (“function implementation”) for each overloaded message (“overloaded function”) are resolved when they are about to be executed. This happens at run time, after the program is compiled. Therefore, polymorphism is given by subtyping polymorphism as in other languages, and it is also extended in functionality by ad hoc polymorphism at run time.

Тоді маю питання. Чи розрзіняються overloading та overriding у Smalltalk?

Цікаве питання. Якщо я правильно пам’ятаю синтаксис Смаллтолку, там оверлоадінг реалізовано за кількістю аргументів. Вказання типу для аргументів немає.
Тобто резолв для оверрайдінгу не буде використовувати механізм резолву для оверлоадінгу, тому що в інших методах інша кількість аргументів.
Треба буде якось завантажити середовище та перевірити.

Наскільки я встиг зрозуміти логіку Smalltalk, тут під час компіляції не має значення, якого типу аргументи передаєш як параметри, тобто будь-яке перевизначення операції з одним і тим самим ім’ям буде мати один і той самий ефект.
Я ж розмірковував з точки зору сильно-типізованих мов, де принципово, аргумент якого типу передаєш, і тут overloading не є проявом поліморфізму. Згідно з принципом спадкування неможливо буде викликати, скажімо, метод giveMeAnswerTo(int addend, int, augend), коли маємо виклик charly.giveMeAnswerTo("Hello, charly!");, а поліморфізм проявляється саме там, де відповідь буде різною залежно від того, ким є charly.

Я тут подумав, що такий самий принцип оверлоадінгу використовуються у сучасних нам JavaScript та Ruby, які знову ж таки є дінамічно типізованими.

Трохи невдало висловився, бо як в JavaScript так і в Ruby ще треба рашпілєм дороблювати :-)

автор новачок і йому потрібно зрозуміти чому йому туфту викладають у відеокурсах, а вам, я бачу, просто кортить потролити товариство :)

туфту
Обґрунтуйте
вам, я бачу, просто кортить потролити товариство :)
не задирайтесь
не задирайтесь
чому ви вважаєте, що я задираюсь? і що таке задиратися у вашій термінології?

ви звинувачуєте мене в тролінґу, замість навести якісь аргументи на користь своєї позициї.

аргументи наводив, але ви їх ігноруєте, дякую за дискусію, але вона не продуктивна. вибачте, якщо в чомусь образив, але з вашою думкою щодо основної теми не погоджуюсь

Ваші аргументи я не ігнорую, а не погоджуюся з ними.

чому йому туфту викладають у відеокурсах
відеокурси до речі досить дорогі, і викладач є сертифікованим тренером Microsoft
автор новачок
нууу, не зовсім так, просто цікава думка інших людей. І як видно з коментів відповідь не однозначна

вибач, якщо зачепило, такий висновок був через саме відео курси :)

та все норм, просто вирішив вивчити щось трохи інше

Поліморфізм полягає в тому, що коли ми викликаємо одну й ту саму функцію з одним і тим самим набором параметрів, звертаючись до об’єктів одного суперкласу, поведінка буде різною, якщо конкретні класи об’єктів різні, і для кожного з цих класів визначено свою відмінну поведінку.
Тож перевантаження методів це не поліморфізм, бо набори параметрів уже неоднакові.

У вас узкий взгляд на этот термин. Погуглите «статический (параметрический) полиморфизм».

Почему у вас, например, obj.toString() - это полиморфизм, а str(obj) — не полиморфизм?

рад вдвойне за варгейминг — игрушки не только хороши снаружи, но, наверное, еще и внутри неплохо устроены

Почнемо з того, що str(obj) не належить до ООП. Тобто це взагалі не стосується питання, яке задав автор.

Начнём с того, что идеология ООП не запрещает использования свободных функций.
Но специально для вас переделаю пример в Utils.str(obj), если вам так будет легче.

Utils.str(obj)
не є поліморфізмом, бо тут ми викликаємо одну й ту саму операцію з різними аргументами, до того ж звертаємось до одного й того самого об’єкта.

Я, разумеется, имею в виду вызовы разных методов:
Utils.str(obj)
Utils.str(vec)
Utils.str(num)
Utils.str(matrix)
и так далее, через overloading.

Тут у якості аргументів вжито різні об’єкти, тож це не поліморфізм. cos(x) поверне різні результати для x = 0.1 та для x = 0.2. Чи можна вважати цю операцію поліморфною?
Поліморфізм це коли різним об’єктам одного класу передають один і той самий аргумент для виконання однієї і тієї ж самої операції, а результат виходить різним залежно від підкласу, до якого належить об’єкт. Наприклад, animal.answer("Hello!") може повернути «", якщо змінна animal представляє об’єкт класу Fish, і «Mieuw!» якщо об’єкт класу Cat.

P.S. Автоматика підмінила програмістські лапки. Спробую ще раз: "" для Fish і "Mieow!" для Cat.

Тут у якості аргументів вжито різні об’єкти, тож це не поліморфізм.

Подскажите, в каком определении полиморфизма вы видели требование “аргументы должны быть одинаковы”?

Нашёл ещё одно определение полиморфизма: “Полиморфизм (polymorphism) (от греческого polymorphos) — это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач”. В принципе, написано верно, и опять же покрывает все случаи.

в каком определении полиморфизма вы видели требование “аргументы должны быть одинаковы”?
Бо це сутність поліморфізму. Чи можна операцію cos(x) вважати поліморфною на підставі того, що для різних аргументів вона видає різний результат?

Не для «разных аргументов», а для разных типов аргументов.

Если ваша операция cos будет работать, например, для float-а и для строки (самостоятельно распарсивая её во float) — будет полиморфной.

Аргументи різного типу, авжеж, будуть різними, вони не можуть бути одним і тим самим аргументом. А поліморфізм стосується саме різної поведінки з одним і тим самим аргументом.

А поліморфізм стосується саме різної поведінки з одним і тим самим аргументом.

Где вы это вычитали?

Я це «вичитав» у декількох книжках про програмування мовою Simula 68, мовою Turbo Pascal (коли він уже став об’єктно-орієнтованим) і мовою C++. Але і в наш час можна про це прочитати. Наприклад, тут: uk.wikipedia.org/...D.D1.8F.D1.82.D1.82.D1.8F

Полиморфизм (polymorphism) (от греческого polymorphos) — это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач
У цьому визначенні не вистачає прив’язки до об’єктно-орієнтованого програмування.

Потому что это определение, а не реализация.

Як це може розв’язати питання, чи вважати overloading поліморфізмом?

Если overloading (который есть в ООП-языке) соответсвует этому определению, значит, является полиморфизмом.

Что у вас с логикой, простите?

Что у вас с логикой, простите?
Не переходьте на особистості
Если overloading (который есть в ООП-языке) соответсвует этому определению
Це омонімія. Нема, наприклад, підстав вважати складання операцією перекладання речей в коробку, коли йдеться про складання цілих чисел у математиці.

Да, потому что в математике среди чисел нет «сложения чисел в коробку». А вот в ООП-языках overloading есть, и связанный с ним полиморфизм — тоже.

коли різним об’єктам одного класу передають один і той самий аргумент для виконання однієї і тієї ж самої операції, а результат виходить різним
Результат може бути різним хоча б тому, що у різних об’єктів, навіть одного класу, буде різний state.

Поліморфізм в ООП (той, який не реалізуєш у процедурному чи функціональному програмуванні) передбачає саме різну реалізацію операції в різних підкласах — коли в програмі не потрібні операції if та typeof.

Было бы неплохо начать с того, что полиморфизм — это не обязательно ООП.

То, что вы этим термином оперируете только в рамках ООП не означает, что
полиморфизм ограничен только применением в ООП.

Вначале с контекстом ознакомьтесь

Да, только-что понял, что пропустил первое слово заголовка :)

Но это не отменяет того факта, что полиморфизм лишь ООП не ограничавается.

Вобщем, проблема данного спора в том, что у термина есть несколько значений, при этом нет общепринятой интерпретации, поэтому этот вопрос довольно холиварный:
stackoverflow.com/...g-considered-polymorphism
stackoverflow.com/...overriding-vs-overloading

никто не спорит что полиморфизм не только ООП
оверлоадинг впервые вроде был использован в процедурных языках

До речі, на властивості поліморфізму ґрунтується принцип підстановки Барбари Лісков uk.wikipedia.org/...ринцип_підстановки_Лісков

все залежить для чого тобі то потрібно. Якщо щоб пройти інтервью -то треба відповідати так як в книжці по якій інтервьювер вчився написано. А там мабуть розрізняють динамічний і статичний поліморфізм і з цієї точки зору overloading можно вважати поліморфізмом (а толку з того? )

Якщо підходити з практичноі точки зору то я для себе не вважаю overloading чимось що відноситься до поліморфізму, коли програмую на джаві бо
1 overloading фактично створює нову функцію з новою сігнатурою, під час виконання вона не буде
2 Тут цікава ситуація з ф-ціями зі змінною кількістю параметрів — ми будемо вважати виклик одноі і функціі з 2 і 3 параметрами поліморфізмом?
3 В реальності нема різниці чи будуть ф-ціі відрізнятися іменами+списком параметрів чи лише списком параметрів. Наприкла в OpenGL є ф-ціі glUniform1f() glUniform2f() glUniform3f() які ніби симулюютть перегрузку імені з використанням суфіксів. Заміна цього підходу на overloading принципово нічого не змінить

Тобто не я не бачу практичної користі з overloading. це фіча ближча до syntax sugar

Абсолютно згоден. Взагалі поняття поліморфізму дуже тісно пов’язане з наслідуванням, визначення якого теж є дуже спірним (бо правильніше та зрозуміліше казати, що один об’єкт є іншим та розширює його, а не є його деріватом). Поліморфізм — це перевикористання коду, а overloading — створення нового.

Якщо щоб пройти інтервью -то треба відповідати так як в книжці по якій інтервьювер вчився написано.
Якби можна було спочатку спитати інтерв’ювера, по якій він книжці вчився.. :)

З точки зору теорії, поліморфізм це виклик функції з одним іменем, але з різними типами аргументів. Є три виду поліморфізму: ad hoc — для кожного типу даних своя окрема реалізація (overloading), parametric — коли один код працює з багатьма типами даних (generic й шаблони у C++). Та останній, subtype — коли виклик методу йде через дані екземпляру класу (virtual, duck, ...).

все залежить для чого тобі то потрібно. Якщо щоб пройти інтервью -то треба відповідати так як в книжці по якій інтервьювер вчився написано
или решить, что “перевешивает” — плюшки, или коллеги с “особым” мнением :)

Overloading — це одна з багатьох імплементацій поліморфізму. Не дивіться відеокурси — практикуйте, потім, коли буде достатньо досвіду, читайте серйозну літературу з архітектури ПЗ.

Що поліморфічного в overloading-у?

одна операція — багато імплементацій (один концепт — багато форм), ні? :)

omg... то есть форма это реализация? если да то вы только что приравняли концепции интерфейсов к классам.... теперь я понимаю почему спрашивают о разнице между интерфейсом и абстрактным классом...

все верно, конкретно в этом случае (overloading): разный набор типов = разные имплементации, даже если вся имплементация — это просто кастинг типов.

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

интерфейс — чистое представление контракта, то есть чистая форма
классы — представляют форму и содержание (реализацию)

если вы говорите что форма = реализация, то вы говорите что интерфейс = класс

как-то так

хорошо, что вы добавили “если”, потому что сложно понять откуда следует

вы говорите что форма = реализация, то вы говорите что интерфейс = класс
ведь здесь не зря в скобках указано теоретическое обобщение (т. к. практическое толкование может быть прочитано неверно при попытке обобщения, что и следует цитаты выше)
одна операція — багато імплементацій (один концепт — багато форм)
в вашем домене есть операция, например, сложение — и у нее много “форм” — сложение (укладка) коробок, сложение (смешивание) газов в трубе и т. д. соответственно у них разные интерфейсы (ваша терминология), а точнее сигнатуры (порядок и типы аргументов), и, на практике, разные имплементации. да, я перешагнул через сигнатуры, но для этого я поставил тире (обычно им заменяется “пропускабельные” промежуточные элементы), но специально добавил пояснения в скобках, дабы было на что дальше сослаться :D
ведь здесь не зря в скобках указано теоретическое обобщение (т. к. практическое толкование может быть прочитано неверно при попытке обобщения, что и следует цитаты выше)
ну полиморфизм вообще исключительно теоретичское понятие описывающие способности принятия множества форм. но проявления этой теории спрашивается в практике, в принципе любая теория имеет проявления только на практике, и без последней лишина смысла.

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

то что называют статическим полиморфизмом, можно рассмотреть как полиморфностью метода, если абстрагироваться от того как оно на самом деле реализуется.

насчет примера с вашим сложением. полиморфизм определяет многоформеность объекта, а не операции

почему операция не может иметь много форм? операция — это активность из домена или функция? как это объект может иметь много форм? и что такое объект? объект домена? инстанс класса? а что такое форма у вас?

если бы было желание продолжать спор, я бы попросил однозначно определить всю терминологию, а потом бы уже продолжил.

мне одно не понятно — принцип простейший, его реализации — еще проще. о чем спор? о том что оверлоадинг не является одной из таких имплементаций? вы так правда считаете? ок!

а если это вам приносит профит — вдвойне ок!

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

почему операция не может иметь много форм? операция — это активность из домена или функция? как это объект может иметь много форм? и что такое объект? объект домена? инстанс класса? а что такое форма у вас?
вроде как про ООП говорили
о чем спор?
вообще я ниже писал, что я понимаю почему так называют и принимаю это, просто я с этим не согласен

Це ж не одна операція. Це дві різні операції, їх обидві не викличеш з одним і тим самим набором аргументів.

під операцією розуміється саме операція з точки зору семантики, а не тіло методу (яке і є формою цієї операції)

Візьмемо операцію cos(x). Якщо її викликати з аргументами x = 0.2 та x = 0.3, вона дасть різний результат. Можна цю операцію вважати поліморфною?

до чого ваш приклад? ви передаєте аргумент того ж самого типу двічі — і у вас в наявності 1 імплементація — який тут поліморфізм? от якщо б ви туди ціле, або строку передали, то так, це був би поліморфізм

оверлоадинг может быть на основе разной арьярности

да, но как это относится к комментарию, на который вы ответили? :)

я на много комментариев ответил. я писал к

до чого ваш приклад? ви передаєте аргумент того ж самого типу двічі — і у вас в наявності 1 імплементація — який тут поліморфізм?
изначальный вопрос был, является оверлоадинг примером полиморфизма, вы вроде как поддержали, но теперь выделяете частные случаи оверлоадинга как полиморфизм.

но, тогда вы сами говорите что оврерлоадинг не является примером его полиморфизма, только некоторые частные примеры

тут многоуровневое дерево, и у комментария есть однозначно вычисляемый родитель, т.е. ответ можно точно адресовать, вы же обращаете внимание на комментарий, под которым кликаете «отвтетить»?

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

неявно исключая при этом вариации оверлоадинга на основе разной арьярности
процитируйте, пожалуйста, где я неявно исключаю

За визначенням, поліморфізм це єдиний інтерфейс для різних типів.

а что такое интерфейс?

«совокупность возможностей, способов и методов одновременного действия»

Так вот operator + (a + b -> c), например, можно признать интерфейсом.

А если работает и (int + int -> int), и (vec + vec -> vec) и (string + string -> string), то такую семантическую перегрузку можно признать полиморфизмом.

вопрос, полиморфизмом чего оно будет? объекта? как в оригинальном определение полиморфизма, или процедуры?

Хлопці, що за неясності, звичайно що поліморфізм, і крапка, не може бути ніяких сумнівів.
Розрізняєте поліморфізм під час рантайм, та під компілейшинтайм. Перегрузка — це компілейшин тайм. І хто каже що поліморфізм — це тільки рантайм поліморфізм, мислить трохи обмежено.

У чому полягає сутність поліморфізму (взагалі)?

В том, что некоторые операции выполняются над разными типами обобщённо, причём на момент написания кода нас не заботит разница между реализациями.

Статический полиморфизм подпадает под это определение.

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

будь ласка, почитайте en.wikipedia.org/...rphism_(computer_science, щоб не плодити сабтреди на цьому форумі (де вже багато разів наводили приклади різних типів поліморфізму — так-так, їх багато!)

У питанні автора йдеться про поліморфізм в ООП. Overloading не є поліморфізмом в ООП.

ви статтю за посиланням читали?

Конкретизуйте питання.
Ось що з звідти можна почерпнути: об’єктно-орієнтованій парадигмі відповідає лише третій тип зі татті: “Subtyping (also called subtype polymorphism or inclusion polymorphism): when a name denotes instances of many different classes related by some common superclass.[3] In the object-oriented programming community, this is often simply referred to as polymorphism”

this is often simply referred to as polymorphism

Согласитесь, что “often simply” — это совершенно не “is OOP one and only”?

сутність не в словах often simply, а в тому, що два інші випадки не стосуються ООП.
“Chris Strachey[4] chose the term ad hoc polymorphism to refer to polymorphic functions that can be applied to arguments of different types, but that behave differently depending on the type of the argument to which they are applied (also known as function overloading or operator overloading). The term ‘ad hoc’ in this context is not intended to be pejorative; it refers simply to the fact that this type of polymorphism is not a fundamental feature of the type system. In the example below, the Add functions seem to work generically over various types when looking at the invocations, but are considered to be two entirely distinct functions by the compiler for all intents and purposes”, тобто тут ми не зможемо просто підставити інший об’єкт, щоб він виконав ту саму операцію. Нам треба буде викликати іншу операцію, хоча і з тим самим ім’ям, і передати їй ще якісь аргументи.
“Parametric polymorphism allows a function or a data type to be written generically, so that it can handle values uniformly without depending on their type.[6] Parametric polymorphism is a way to make a language more expressive while still maintaining full static type-safety”, тобто тут теж не йдеться про поліморфізм операцій.
А третій тип це саме той поліморфізм, який ми обговорюємо.

А, ну в этом смысле да — статический полиморфизм не является отличительным свойством ООП-языка. Отличительным является динамический.

НО

Вспоминаем, с чего началось обсуждение — с вопроса «является ли overloading полиморфизмом [в ООП-языке]?». И снова-таки — да, является, хотя это НЕ отличительное свойство ООП-языка.
Так яснее?

Ніколи не розумів таких людей, які задають питання, а потім самі на нього «типу» правильно відповідають, завжди ідентифікую вас як тролів :-)

Ми в решті решт дійшли спільного конструктивного висновку, а ви тим часом можете продовжувати ідентифікувати нас як тролів. :)

Екель в «Філософії джава» пише, що це поліморфізм часу компіляції, а відповідно overriding — часу ваконання.

Я думаю, що будь яку річ можна назвати трамваєм, якщо про це узгодитися.

Більшість термінів нам знайомо з практики, а не з теоретичного обґрунтування. А практика це частковий випадок, тому визначення з контексту не можуть бути однозначно відтворені. Тому не дивно, що хтось вважає, що слово «поліморфізм» стосується лише виклику функції через таблицю методів (subtype polymorphism, inclusion polymorphism).

Страуструп считает это полиморфизмом функций.

Думаю, що на цьому можна завершити обговорення і закрити тему)

Поліморфність=багатоформеність. Тобто якась сутність може приймати одну чи іншу форму. Тобто сутність — це метод, а форма його — це реалізація. Будь які суперечки виникають через брак дефініцій :-). Такщо перевантаження методу — поліморфізм статичний, тобто рішення про те яку форму прийме метод приймається підчас компіляції. Наприклад лябда функція передана до іншої як параметр — теж форма поліморфізму. Можна піти далі і назвати змінну поліморфною сутністю. Але усе це цікаво з точки зору академічних вправ. Практичного значення у таки питаннях мало...

Практичного значення у таки питаннях мало...
Практичне значення лише одне — пройти співбесіду. :)

Ну тогда отвечать надо с фразы: «на этот счет бытуют разные мнения...»

Только при оверлоадинге методы разные, сигнатура не только имя метода, но и аргументы

Хех, ваша правда, треба було уточнити що я мав на увазі саме назву, не сигнатуру. Якщо брати сигнатуру то і динамічний поліморфізм — не поліморфізм :-). Адже x.f(y) просто синтаксична зручнсть, могло б бути і так: f(x,y). Тобто належність методу до іншого класу майже те саме що метод мав би перший параметр іншого типу (іншу сигнатуру). Для того щоб поліморфізм реалізувати методи таки мають чимось відрізнятися :-).

не, то что называется динамическим полиморфизмом то ок.
x.f(y) — тут y — можеть быть полиморфным, ибо мы условно ожидаем y — как класс А, а реально y — представитель класса Б, но в этом проявляетс его полиморфность.

когда называют overloading полиморфизмом, то для меня это как-то странно, если сигнатура представлена только именем, тогда это будет полиморфностью x — и да, если забыть то как оно есть (или не знать), то это смело можно назвать полиморфностью.

я понимаю что народ тупо запомнил, и не думает сам. просто если попытатся разобратся то сразу вся логика за статическим полиморфизмом сыпется

Можливо ваша правда. Усі інші «поліморфізми» не дають головного: dependency inversion. Тому може й не варто розглядати їх як поліморфізм.

вот и я о чем.

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

Я вот подумал с другой стороны, а какой смысл в этом вопросе на собеседовании?
Ну вот допусти overloading это полиморфизм, но ведь он не перестает быть генератором костылей

stackoverflow.com/...atic-polymorphism-in-java

Static polymorphism : Same method name is overloaded with different type or number of parameters in same class (different signature). Targeted method call is resolved at compile time.

Dynamic polymorphism: Same method is overridden with same signature in different classes. Type of object on which method is being invoked is not known at compile time but will be decided at run time.

На співбесдах, коли виникало таке питання, завждив наводив overloading як приклад поліморфізму, завжди інтерв"юєр зі мною погоджувався.

аналогічно, більше того навіть вказували що це поліморфізм коли я не називав

В такому випадку робіть висновок про компетентність лектора курсів.

overloading это создание многих функций, с частично одинаковой сигнатурой
полиморфизм это про способность представления одного объекта как другого

overloading, если правильно используется, может быть представлением полиморфизма с точки зрения логики, но не с реальной (ибо функция будет реально другая применина), но даже его использование для полиморфизма, признак проблем в общем дизайне системы.

UPD: не обязательно проблемы дизайна системы, может быть вызвыно ограничениями/спецификой языка

Да, является полиморфизмом времени компиляции.
Просто часто под полиморфизмом подразумевают только «времени выполнения», что и вводит в заблуждение.

Wiki:

In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types. A polymorphic type is one whose operations can also be applied to values of some other type, or types.

overloading по факту определяет функцию с новой сигнатурой, и когда называют это полиморфизмом, то как по мне это явное непонимание теории.

хотя название ad-hoc полиморфизм как по мне валидно из-за распространености и из название ясно что это по факту костыль для полиморфизма, а не он в чистом виде

Чи то overloading, чи то overriding — обидва поняття відносяться до поліморфізму (а точніше до одногу з типів поліморфізму).

Оverloading — у більшості випадків можна назвати поліморфізмом під час компіляції (Compile Time Polymorphism).
Оverriding — поліморфізм під час виконання (Run Time Polymorphism).

Хоча є люди, які думають інакше, тому краще десь вам самому відшукати в книжках це, і в разі такого запитання посилатися на них.

Лучше говорить в терминах overloading и overriding. Так по крайней мере можно хоть ссылаться на литературу и статьи. А если мы будем интерпретировать термин то получим к примеру вместо приложения — аппликацию или всместо thread — нить (что само по себе читается бредово) и путает нас.

OK, погоджуються з Вами, зараз поміняю

Не поліморфізм.

А чому саме можете сказати? Як пишуть в підручниках Поліморфізм — це виконання одного і того самого методу різними способами. Перегрузка підходить в принципі під це визначення. На співбесідах коли здають питання про полфіморфізм переважно очікують що відповідь буде overriding, overloading і type casting

А чому саме можете сказати?
Якщо поміняти ім’я в overloaded методі, щоб воно стало унікальним, будуть питання про поліморфізм?

Компілятор всі імена фукцій перетворює в унікальні імена, додаючи тип параметрів, схему виклику і ще деякі керуючі символи.

Поліморфізм — це виконання одного і того самого методу різними способами
Тому, оverloaded метод, не той самий метод, а інщий метод, унікально перейменований компілятором.

Доречі в Вікіпедії (uk.wikipedia.org/...ki/Перевантаження_функці) сказано:


Перевантаження методів не слід плутати з поліморфізмом, при якому потрібний метод обирається під час виконання, за допомогою віртуальних методів, замість статичних.

Але ж там також пише:

Перевантаження функцій відноситься до класифікації статичного поліморфізму

The Java Tutorials визначає Поліформізм як: властивість классів, що наслідують поведінку — створювати свою специфічну поведінку для тієй ж самої функціональності.
docs.oracle.com/...a/IandI/polymorphism.html
The dictionary definition of polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.

Таким чином, основне питання для уточнення поняття Поліформізму — ви можете формулювати це поняття незалежно від Наслідування? Чи Поліформізм є нерозривно взаємозв’язаним з Наслідуванням?
Якщо ви маєте право розглядати їх окремо, то визначення:

Поліморфізм — це виконання одного і того самого методу різними способами
можливе.
Але якщо Поліформізм з’являється тільки у зв’язку з Наслідуванням, то таке визначення неточне.

Тобто, історично є два підходи до пояснення Поліформізму, тут в розділі History:
en.wikipedia.org/...rphism_(computer_science
є перша згадка про Поліформізм у 1967 року, де в статті британського комп’ютерного науковця були описані Ad hoc polymorphism та parametric polymorphism.
А Поліформізм, як його формулюють при вивченні Java сформульований у 1985 році — «inclusion polymorphism to model subtypes and inheritance».

Таким чином маємо 2 контекста для питання, що таке Поліформізм.

І тут так само: Поліморфізм.

Подписаться на комментарии