Полиморфизм - определение всего в двух предложениях [закрыто]


85

Я просмотрел другие определения и объяснения, и ни одно из них меня не удовлетворило. Я хочу посмотреть, сможет ли кто-нибудь определить полиморфизм не более чем в двух предложениях без использования кода или примеров. Я не хочу слышать «Итак, у вас есть человек / машина / консервный нож ...» или как это слово образовано (никого не впечатляет, что вы знаете, что означают поли и морфинг). Если вы хорошо понимаете, что такое полиморфизм, и хорошо владеете английским языком, тогда вы сможете ответить на этот вопрос в кратком, хотя и плотном, определении. Если ваше определение точно определяет полиморфизм, но настолько плотно, что требует нескольких повторений, то это именно то, что я ищу.

Почему всего два предложения? Потому что определение короткое и разумное. Объяснение длинное и содержит примеры и код. Поищите здесь объяснения (ответ на этих страницах не является удовлетворительным для моего вопроса):

Полиморфизм против переопределения против перегрузки
Попытайтесь описать полиморфизм как можно проще

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

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


Одно имя, множественная реализация.
Просунджит Бисвас,

2
Мне задали этот вопрос на собеседовании. Я чувствовал, что вопрос об этом на собеседовании был элитарным актом снобизма, вроде того, что сотрудник Google самодовольно спрашивает, полагая, что никто не сможет ответить на него эффективно. Если вы не получили работу, потому что не смогли ответить, вам, вероятно, лучше работать с людьми, которых больше интересует то, что вы можете сделать, а не тех, кого вы можете перехитрить.
MagicLAMP

Полиморфизм - очень важное понятие, которое нужно понимать при разработке. Я настоятельно рекомендую хотя бы понять его ценность, если не формальное определение. Я предлагаю как минимум объяснить, как работает паттерн Стратегия, и его значение.
Чад Джонсон

Ответы:


106

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

(*) Во всяком случае, в идеальном случае - очевидно, что часто вызывающий код выбирает подходящую реализацию осознанно!


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

То же самое, Джон - у меня есть 2 принятых ответа с -15 повторениями. Не то чтобы меня это волновало, но это интригует.
Otávio Décio, 03

3
Строго говоря, нет требования, чтобы «один тип выражал какой-то контракт». Все, что действительно требуется, - это то, что несколько реализаций могут отвечать на одно и то же сообщение, при этом отправителю сообщения не нужно знать или заботиться о том, какая реализация обрабатывает сообщение.
Дуг Кнесек

3
@Doug: Если нет контракта, даже подразумеваемого в документации или именовании, то откуда вы знаете, что он будет делать то, что вы хотите? Вы говорите об «интерфейсе» в своем собственном ответе - что для меня очень похоже на контракт - в чем вы видите разницу? И «интерфейс», и «контракт» - это слова, которые могут использоваться в «строгом» смысле (например, принудительно во время компиляции) или очень свободно (например, посредством соглашения об именах и использования динамической типизации).
Джон Скит

1
@Alex: Да, я бы отменил эту правку - я предпочитаю свою формулировку. Однако вы всегда можете добавить свой ответ.
Джон Скит

72

Как правило, фрукты можно есть, но разные фрукты едят по-разному. Яблоко, которое является фруктом, можно есть (потому что это фрукт). Банан тоже можно есть (потому что это тоже фрукт), но иначе, чем яблоко. Вы сначала очистите его.

Ну, по крайней мере, знаю, но в некоторых манерах я странный, так что я знаю.

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

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


lassevk: «если вы уже не знаете, что это такое, вы не узнаете об этом достаточно, чтобы знать, о чем вам нужно узнать больше» << Чтобы уточнить, это то, что я ожидаю. Я ищу определение, для понимания которого, возможно, потребуется некоторое время. Не тот, который использовался бы для обучения новичка.
Марк Теста,

2
Я так понял, я только что опубликовал несколько юмористический (по крайней мере, для меня) ответ :) Полиморфизм и ООП - одна из тех больших стенок, когда, если вы изобразите кривую обучения, вы просто попадаете в большую стену и либо ползаете по ней , или нет. Если да, то обычно у вас большая АГА! опыт ...
Лассе В. Карлсен

8
Болиголов - тоже фрукт! Его можно съесть, но только один раз!
Джеймс Андерсон,

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

47

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


Это удивительно лаконично, и я думаю, что это идеально подходит
Alex W

21

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


21

На самом деле, существует множество форм полиморфизма, и по этому поводу ведутся споры; вы даже можете встретить профессоров CS, которые не могут дать ему правильного определения. Мне известны три типа:

  • специальный полиморфизм (выглядит как утка и ходит как утка => это утка). Его можно увидеть, например, в Haskell и Python.

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

  • полиморфизм подтипа (когда тип наследуется от другого типа). Его можно увидеть в большинстве языков программирования OO (т.е. треугольник - это форма).


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

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

@LaurenceGonsalves fwiw, ссылка в первом комментарии действительно указывает на три типа. Параметрический полиморфизм определяется как возможность записи функции или типа данных «в общем».
Shanimal

14

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

Возможность объектов одного типа иметь один и тот же интерфейс, но разную реализацию этого интерфейса.


10

Определение :

Полиморфизм - это слово за 10 долларов для идеи за 1 доллар: когда я прошу что-то сделать, меня не волнует, как это достигается, если конечный результат подходит. Пока сервис правильно при условии, я не забочусь о реализации .

Обсуждение

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

Примеры

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

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


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

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

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 - это не просто особый вид полиморфизма подтипа, где родительский тип полностью абстрактный? Или вы имеете в виду другое?
Николас Ринаудо

Мое намерение интерфейса - это интерфейс как ссылочный тип, который существует в объектно-ориентированных языках, например: Интерфейс I1 {void M ();} Я действительно считаю, что существует так много различий между подтипом или полиморфизмом на основе наследования и полиморфизмом на основе интерфейса . Потому что в полиморфизме на основе наследования между типами существует связь «Is-a», но в полиморфизме, основанном на интерфейсе, такого нет. Фактически, одно и то же поведение с разными реализациями может быть общим для разных типов (классов)
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, все будут типа check. Именно это и означает полиморфизм подтипа.
Николас Ринаудо,

Bird, Person и Car не являются подтипами Imobile, они являются разработчиками этого интерфейса и «осознают» этот интерфейс по-своему. Термин «подтип» широко используется между реальным типом и реальным подтипом, унаследованным от него, и в этой ситуации между ними существует связь «Есть-а», например, собака является подтипом млекопитающего.
siamak

с точки зрения компилятора ссылка на интерфейс и использование ссылок является чем-то верным и правильным. / НО / IT - это не одно и то же понятие с подтипами в отношениях наследования. И я думаю, что называть разработчиков интерфейса как подтипов очень неудобно и на самом деле неправда.
siamak

Пример полиморфизма, основанного на наследовании, уместно объяснить этот ответ.
Марсело Мейсон

5

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

Павел.


5

полиморфизм == несколько классов + одинаковые сигнатуры методов + поведение, зависящее от класса.


2

Множественные формы одного объекта называется полиморфизмом.


2

Полиморфизм

Различные объекты могут реагировать на одно и то же сообщение по-разному, позволяя объектам взаимодействовать друг с другом, не зная их точного типа.

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


2

Полиморфизм - это способность объекта выглядеть и вести себя по-разному при одном и том же вызове. Пример: каждое животное выглядит и звучит по-разному (когда вы его ударяете :))


2

Полиморфизм - это особенность языков программирования, которая позволяет рассматривать объект как экземпляр его супертипа.


Downvoter - Объясните, пожалуйста, почему?
TarkaDaal

1

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


1

Это определение, которому я всегда следовал:

Два объекта полиморфны (по отношению к определенному протоколу) между ними, если оба отвечают на одни и те же сообщения с одинаковой семантикой.

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

Если два объекта МОГУТ ответить на пустой? но семантика сообщения другая, значит .. они не полиморфны.


1

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


1

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


1

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

(Типы, поддерживаемые C ++, перечислены и противопоставлены в моем ответе: Полиморфизм в C ++ )


0

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

Вы можете определить список следующим образом:

List list = new List();

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

IList list = new List();

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

Теперь поступает более ценная информация:
Java по умолчанию полиморфна, тогда как .NET и C ++ не являются, в MS вы должны объявить базовую функцию virtualoverrideключевое слово .NET ).

Кроме того, в полиморфизме есть 2 интегральных правила. Один из них - наследование (через имплантированный интерфейс или через расширение класса), а другой - переопределение. Без переопределения полиморфизма не существует. Обратите внимание, что перегрузка метода (которая всегда в одном классе) также является типом «минималистичного» полиморфизма.


1
Это более двух предложений.
Dangerous

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.