Поліморфізм - Визначте у двох реченнях [закрито]


85

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

Чому лише два речення? Тому що визначення коротке і розумне. Пояснення довге і містить приклади та код. Шукайте тут пояснення (відповідь на цих сторінках не відповідає моєму питанню):

Поліморфізм проти перевизначення проти перевантаження
Спробуйте описати поліморфізм якомога простіше

Чому я задаю це питання? Оскільки мені задали те саме запитання, і я виявив, що не зміг дати задовільного визначення (за моїми стандартами, які досить високі). Я хочу подивитися, чи зможе це зробити хтось із великих розумів на цьому сайті.

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


Одне ім'я, багаторазове впровадження.
Просунджіт Бісвас

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

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

Відповіді:


106

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

(*) У ідеальному випадку, так чи інакше - очевидно, досить часто телефонний код дуже навмисно вибирав відповідну реалізацію!


1
Марк, ти в один момент прийняв цю відповідь, а потім не прийняв? Я намагаюся зрозуміти, що схоже на помилку в системі репутації - ця відповідь дала мені чистий показник -15 на сьогоднішній день, як не дивно.
Джон Скіт

Те саме тут, Джон - я вже прийняв 2 відповіді з показником -15. Не те, що я дбаю, але це інтригує.
Otávio Décio

3
Власне кажучи, немає вимоги, щоб "один тип виражав якийсь договір". Все, що насправді потрібно, це те, що декілька реалізацій можуть відповісти на одне і те ж повідомлення, без того, щоб відправнику повідомлення не потрібно було знати чи дбати, яка реалізація обробляє повідомлення.
Doug Knesek

3
@Doug: Якщо немає договору, навіть передбаченого документацією чи іменами, то звідки ти знаєш, що він буде робити те, що ти хочеш? Ви говорите про "інтерфейс" у своїй власній відповіді - це дуже схоже на контракт - у чому ви бачите різницю? І "інтерфейс", і "контракт" - це слова, які можна використовувати у "сильному" значенні (наприклад, примусово застосовувати під час компіляції) або дуже вільно (наприклад, шляхом дотримання імен та використанням динамічного набору тексту).
Джон Скіт,

1
@ Alex: Так, це було б правом, яке я скасував би - я віддаю перевагу своїм формулюванням. Ви завжди можете додати власну відповідь.
Джон Скіт,

72

Фрукти можна їсти, як правило, але різні види фруктів їдять по-різному. Яблуко, яке є фруктом, можна їсти (бо це фрукт). Банан також можна їсти (оскільки це теж фрукт), але не так, як яблуко. Ти спочатку його очисти.

Ну, принаймні я це роблю, але я дивний у деяких манерах, так що я знаю.

Це ілюструє успадкування (фрукти можна їсти), поліморфізм (те, що їсть фрукти, може їсти всі види фруктів) та інкапсуляцію (банан має шкірку).

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


lassevk: "якщо ти вже не знаєш, що це таке, ти не дізнаєшся про це достатньо, щоб знати, про що тобі потрібно дізнатись більше" << Тільки для уточнення, саме цього я очікую. Я шукаю визначення, яке, можливо, потребує певної думки для розуміння. Не той, який був би використаний для навчання новачка.
Марк Теста

2
Я зрозумів це, я просто опублікував дещо жартівливу (мені в будь-якому випадку) відповідь :) Поліморфізм і ООП - це одна з тих великих стін, де, якщо ви графікуєте криву навчання, ви просто потрапляєте у велику стіну, або ви повзаєте по ній , чи ні. Якщо ви це робите, то у вас зазвичай великий AHA! досвід ...
Лассе В. Карлсен

8
Болиголов - це теж плід! Їсти його можна, але лише один раз!
Джеймс Андерсон,

@JamesAnderson Отже, синглтон?
Лассе В. Карлсен,

47

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


Це напрочуд лаконічно, і я думаю, що воно цілком підходить
Алекс В,

21

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


21

Насправді існує багато форм поліморфізму, і щодо нього існує певна суперечка; Ви навіть можете побачити професорів CS, які не можуть визначити це належним чином. Мені відомі три типи:

  • спеціальний поліморфізм (виглядає як качка і ходить як качка => є качкою). Наприклад, це можна побачити в Haskell та Python.

  • загальний поліморфізм (де тип є екземпляром якогось загального типу). Наприклад, це можна побачити в C ++ (вектор типу int та вектор рядка мають розмір функції-члена).

  • підтип поліморфізму (де тип успадковується від іншого типу). Це можна побачити в більшості мов програмування OO (тобто Трикутник - це форма).


2
+1 за згадку про те, що існують різні типи поліморфізму. Однак, ваше визначення спеціального поліморфізму, схоже, значно відрізняється від того, що згадується на en.wikipedia.org/wiki/Type_polymorphism . На цій сторінці сказано, що існує 2 типи (спеціальні проти параметричних), а не 3, а також розрізняють поліморфні функції та поліморфні типи даних. Ваші 3 типи, наскільки я можу визначити, відповідають параметричним поліморфним функціям, параметричним поліморфним типам даних та спеціальним поліморфним функціям, відповідно.
Лоуренс Гонсалвес,

привіт, яка різниця між "екземпляром якогось загального типу" та "успадковується від іншого типу", схоже, вони говорять про те саме?
Шанімаль

@LaurenceGonsalves fwiw, посилання, подане в першому коментарі, вказує на три типи. Параметричний поліморфізм визначається як дозволяючи функцію або тип даних писати "загально".
Шанімаль

14

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

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


10

Визначення :

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

Обговорення

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

Приклади

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

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


5
Encapsulationдля мене звучить як приклад
Сінглтон

1
Поліморфізм, інкапсуляція та абстракція досить тісно пов'язані, хоча вони зосереджені на різних перспективах. Хороші абстракції полегшують досягнення поліморфізму, а хороша інкапсуляція допомагає запобігти «витоку» деталей.
Беван,

10

Кілька реалізацій одного і того ж інтерфейсу.

Приклад: Багато моделей телефонів реалізують інтерфейс цифрової клавіатури.


8

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

Гаразд, важко ....


7

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

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

Спеціальний поліморфізм

Спеціальний поліморфізм - це акт надання кількох реалізацій одного і того ж методу для різних типів параметрів. В ООП це загальновідомо як перевантаження методів . Наприклад:

public String format(int a) {
    return String.format("%2d", a);
}

public String format(Date a) {
    return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(a);
}

Обидва formatметоди мають єдиний інтерфейс , але вони працюють над сутностями різних типів .

Параметричний поліморфізм

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

Наприклад, Java List[T]очікує параметр Tпід час встановлення, і цей параметр визначає тип результуючого об'єкта.

Зауважте для пуристів, що я цілеспрямовано ігнорую сирі типи, оскільки, на мою думку, вони просто мутять воду в цьому контексті.

List[String]і List[Date]мають єдиний інтерфейс , але працюють над (і є) різними типами .

Підтип поліморфізму

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

Для використання звичного прикладу: Animalнадає контракт, який повинні виконувати всі реалізації. Dogє Animal, і як такий підтримує всі операції, які Animalоголошує. Згідно з принципом заміщення Лісковим , це дозволяє використовувати екземпляр, Dogде екземпляр Animalочікується (але не навпаки).

Якщо Catі Dogє обома підкласами Animal, то вони мають єдиний інтерфейс, але насправді є різними типами .

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


так як щодо поліморфізму на основі інтерфейсу?
siamak

@siamak - це не просто конкретний вид поліморфізму підтипу, де батьківський тип є абсолютно абстрактним? Або ти маєш на увазі щось інше?
Ніколас Рінаудо,

Моїм наміром інтерфейсу є Interface як еталонний тип, який існує в об’єктно-орієнтованих мовах, наприклад: Interface I1 {void M ();} Я вірю, що існує так багато відмінностей між підтипом або поліморфізмом, заснованим на спадщині, та поліморфізмом на основі інтерфейсу . Оскільки в поліморфізмі, заснованому на спадщині, існує взаємозв'язок "Є-а", але в поліморфізмі, що базується на інтерфейсі, такого немає. Насправді однакова поведінка з різними реалізаціями могла б ділитися між різними типами (класами)
siamak

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

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

6

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

Існує два види поліморфізму:

1. Compile-time (static) polymorphism or (ad hoc) polymorphism.

Це просто перевантаження методів та перевантаження оператора

2.  Run time or (dynamic) polymorphism.

Перший термін успадкований від термінології Java та C ++.

Але в термінології .NET лише другий ( я маю на увазі поліморфізм часу виконання ) насправді вважається поліморфізмом і називається просто поліморфізмом .

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

 1. Parametric polymorphism or simply the use of generics (templates in C++).

 2. Inheritance-based polymorphism or subtyping.

 3. Interface-based polymorphism.

Простий приклад поліморфізму на основі інтерфейсу:

interface Imobile
{
    void Move();
}

class Person :Imobile
{
    public void Move() { Console.WriteLine("I am a person and am moving in my way."); }
}

class Bird :Imobile
{
    public void Move() { Console.WriteLine("I am a bird and am moving in my way."); }
}

class Car :Imobile
{
    public void Move() { Console.WriteLine("I am a car and am moving in my way."); }
}


class Program
{

    static void Main(string[] args)
    {
        // Preparing a list of objects
        List<Imobile> mobileList = new List<Imobile>();

        mobileList.Add(new Person());
        mobileList.Add(new Bird());
        mobileList.Add(new Car());

        foreach (Imobile mobile in mobileList)
        {
            mobile.Move();
        }

        // Keep the console open
        Console.WriteLine("Press any key to exit the program:");
        Console.ReadKey();
    }
}

Вихід:

 I am a person and am moving in my way.
 I am a bird and am moving in my way.
 I am a car and am moving in my way.
 Press any key to exit the program:

Я все ще не бачу різниці, яку ти робиш. Людина, Птах та Автомобіль - все це підтипи Imobile. Людина - нерухомий, птах - нерухомий, а автомобіль - нерухомий. Якщо вам потрібна змінна типу Imobile, ви можете використовувати або екземпляр Person, Bird або Car, всі вони перевіряють тип. Саме це означає поліморфізм підтипу.
Ніколас Рінаудо

Птах та Людина та Автомобіль не є підтипами Imobile, вони є Втілювачами цього Інтерфейсу та "реалізують" цей Інтерфейс по-своєму. Термін "підтип" широко використовується між реальним Типом та реальним підтипом, який успадкував від нього, і в цій ситуації між ними існує взаємозв'язок "Є-а", наприклад, собака - це підтип ссавця.
siamak

з точки зору компілятора, посилання на інтерфейс та використання посилань є чимось правдивим і правильним. / АЛЕ / ІТ не є рівнозначним поняттям із підтипуванням у відносинах спадкування. І я думаю, що називати реалізаторів інтерфейсу як підтипи настільки незручно і насправді не так.
siamak

Приклад поліморфізму на основі спадщини було б добре пояснити на цю відповідь.
Марсело Мейсон

5

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

Павло.


5

поліморфізм == декілька класів + однакові підписи методів + поведінка класу.


2

Кілька форм одного об’єкта називається поліморфізмом.


2

Поліморфізм

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

Через: http://www.agiledata.org/essays/objectOrientation101.html


2

Поліморфізм - це здатність об’єкта з’являтися і поводитися по-різному за одного і того ж виклику. напр .: кожна тварина з’являється і звучить по-різному (коли ти вдариш її :))


2

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


Даунвотер - не могли б ви пояснити, чому?
TarkaDaal

1

Присвоєння єдиного імені набору аналогічних операцій над різними типами. Якщо все зробити добре, аналогія очевидна, наприклад, «додавання» чисел арифметично та «додавання» рядків шляхом об’єднання (що підсумовує їх довжини).


1

Це визначення, якого я завжди дотримувався:

Два об'єкти є поліморфними (щодо певного протоколу) між собою, якщо обидва відповідають на однакові повідомлення з однаковою семантикою.

Поліморфізм - це повідомлення, це можливість відповідати на один і той же набір повідомлень однаковою семантикою.

Якщо два об'єкти можуть відповісти на порожній? але семантика повідомлення інша, тоді .. вони не є поліморфними.


1

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


1

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


1

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

(Типи підтримуваних C ++ перераховані та протиставлені у моїй відповіді: Поліморфізм у c ++ )


0

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

Ви можете визначити список наступним чином:

List list = new List();

але якщо ви перевірите IList, ви можете скористатися інтерфейсом як:

IList list = new List();

і IListвільно використовувати посилання. Припускаючи IList, що також реалізовано в іншому класі, ви можете знову використовувати методи цього невідомого класуIList посилання, не намагаючись запам'ятати це ім'я класу. Чудово, чи не так?

Тепер з’являється більш цінна інформація:
Java за замовчуванням є поліморфною, тоді як .NET та C ++ - ні, в MS вам потрібно оголосити базову функцію virtual(та в overrideключовому слові .NET ).

Крім того, у поліморфізмі є 2 інтегральні правила. Один - це успадкування (за допомогою інтерфейсу impl. Або за допомогою розширення класу), а інший є переважним. Без перевизначення, поліморфізм не існує. Зауважте, що перевантаження методів (яка завжди в одному класі) також є різновидом "мінімалістичного" поліморфізму.


1
Це більше 2 речень.
Небезпечно

0

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


0

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

Тобто: в Java, як ArrayList, так і LinkedList обидва реалізують List, якщо ви оголосите змінну як List, ви завжди можете виконувати операції, дозволені в List, незалежно від того, якщо ця змінна була інстанційована як ArrayList або LinkedList.


0

Суб'єкти одного типу (тобто реалізовані одним інтерфейсом або отримані з одного класу) поводяться по-різному (під однією назвою методу).


0

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


-2

Думаю, іноді об’єкти викликаються динамічно. Ви не впевнені, чи буде об’єкт трикутником, квадратом тощо у класичній формі полі. приклад.

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

Вам все одно, це квадратура, трикутник або прямокутник. Ви просто дбаєте про територію. Отже, метод getArea буде викликаний залежно від переданого динамічного об'єкта.


-2

Поліморфізм - це здатність функції автоматично адаптуватися до прийому вхідних даних різних типів даних. Ви можете 'Додати' два подвійні '1.1' та '2.2' та отримати '3.3' або 'Додати' два рядки "Стек" та "Переповнення" та отримати "StackOverflow".


Чому хтось це відзначив - це «буквальна відповідь» на веб-сторінці National Instrument про поліморфізм !!!
J-Dizzle

-3

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


Насправді, поліморфізм розглядає екземпляри різних класів як загальний тип, і він міг використовувати методи, оголошені в цьому загальному типі, незалежно від того, як різні класи реалізують ці методи.
GaRRaPeTa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.