Попробуйте описать полиморфизм так просто, как вы можете

Как можно описать полиморфизм легко понятным способом?

Мы можем найти много информации о предмете в Интернете и в книгах, например, в Тип полиморфизма. Но постарайтесь сделать все как можно проще.

Ответ 1

Это из моего ответа по аналогичному вопросу. Вот пример полиморфизма в псевдо-С#/Java:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

Метод Main() не знает тип животного и зависит от конкретного поведения реализации метода MakeNoise().

Ответ 2

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

Ответ 3

Каждый может с простой поп-крышкой открывается таким же образом.
Как человек, вы знаете, что можете открыть() любое такое, что можете найти.

При открытии не все банки ведут себя одинаково.
Некоторые содержат орехи, в некоторых из которых есть поддельные змеи, которые выходят.
Результат зависит от того, какой ТИП может быть, если банда была "CanOfNuts" или "CanOfSnakes", но это не имеет никакого отношения к тому, как вы ее открываете. Вы просто знаете, что можете открыть любую Can, и получите какой-то результат, который будет решаться на основании того, какой тип может быть вы открыли.

pUnlabledCan- > Open();//может дать орехи, может дать змей. Мы не знаем, пока не назовем его

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

Вы, человек, являетесь пользователем/вызывающим.
Open() - это виртуальная/полиморфная функция.
"Может" - абстрактный базовый класс.
CanOfNuts и CanOfSnakes - это полиморфные дети класса "Can".
Каждая Can может быть открыта, но что конкретно она делает и какая конкретная информация о содержимом, которую она возвращает, определяется тем, что она может быть.
Все, что вы знаете, когда вы видите pUnlabledCan, это то, что вы можете открыть() он, и он вернет содержимое. Любые другие виды поведения (такие как появляющиеся змеи в вашем лице) определяются конкретным Can.

Ответ 4

Простейшим описанием полиморфизма является то, что это способ уменьшить if/switch statements.

Это также дает вам возможность расширить ваши операторы if/switch (или другие люди) без изменения существующих классов.

Например, рассмотрим класс Stream в .NET. Без полиморфизма это был бы один массивный класс, в котором каждый метод реализует оператор switch что-то вроде:

public class Stream
{
    public int Read(byte[] buffer, int offset, int count)
    {
        if (this.mode == "file")
        {
            // behave like a file stream
        }
        else if (this.mode == "network")
        {
            // behave like a network stream
        }
        else // etc.
    }
}

Вместо этого мы позволяем среде выполнения выполнять переход для нас более эффективным способом, автоматически выбирая реализацию на основе конкретного типа (FileStream, NetworkStream), например

public class FileStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a file stream
    }
}

public class NetworkStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a network stream
    }
}

Ответ 5

Поли: много
Морфизм: формы/формы

Ответ 6

Актер против персонажа (или роли)

Ответ 7

Яблоки и апельсины - оба плода. Фрукты можно есть. Следовательно, можно употреблять как яблоки, так и апельсины.

Кикер? Вы едите их по-другому! Вы очищаете апельсины, но не яблоки.

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

Ответ 8

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

Ответ 9

Это действительно лучшая статья

Полиморфизм позволяет объектам "смотреть" одно и то же, но вести себя по-разному. Обычный пример состоит в том, чтобы взять базовый класс животных с помощью метода Speak(), подкласс Dog будет испускать Bark, тогда как подкласс Pig выпустит oink.

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

Ответ 10

Тот же синтаксис, различная семантика.

Ответ 11

Простейший способ описать это: глагол, который может применяться к нескольким типам объектов.

Все остальное, как сказал Хиллел, просто комментирует.

Ответ 12

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

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

Как немного лишний, вы можете сделать это, даже если Animal является "абстрактным" идентификатором (нет реальной вещи "Animal", только типы животных).

Ответ 13

Полиморфизм - это хранение значений более одного типа в местоположении одного типа.

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

Динамическая отправка требует полиморфизма, но обратное неверно. Можно представить себе язык, очень похожий на Java или С#, но у которого System.Object не было участников; необходимо было бы прибегнуть к типе, прежде чем делать что-либо со значением. В этом условном языке существовали бы полиморфизм, но не обязательно виртуальные методы или любые другие динамические механизмы рассылки.

Динамическая отправка - это связанная, но отличная концепция, достаточно хорошо описанная в большинстве других ответов. Однако способ, которым он обычно работает в объектно-ориентированных языках (выбор функции, основанной на первом типе аргументов ('this' или "я" ), - это не единственный способ, которым это может работать. Также возможна множественная отправка, где выбор применяется к типам всех аргументов.

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

Ответ 14

Полиморфизм - это то, что вы получаете, когда один и тот же метод применяется к нескольким классам. Например, как строка, так и список могут иметь "обратные" методы. Оба метода имеют одно и то же имя ( "Реверс" ). Оба метода делают что-то очень похожее (отмените все символы или измените порядок элементов в списке). Но реализация каждого метода "Обратный" отличается и специфична для его класса. (Другими словами, String меняет себя как строку, и List перестраивается как список.)

Чтобы использовать метафору, вы можете сказать "Ужин" французскому шеф-повару или японскому шеф-повару. Каждый из них будет выполнять "приготовление обеда" своим собственным характерным способом.

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

Чтобы расширить аналогию с шеф-поваром, вы можете создать "Waiterbot", который говорит шеф-поварам "Make Dinner". Waiterbot не должен знать, какой тип обеда будет сделан. Это даже не обязательно, чтобы он говорил с шеф-поваром. Все, что имеет значение, - это то, что "шеф-повар" (или пожарный, или торговый автомат, или раздатчик кормов для домашних животных) знает, что делать, когда он сказал "Сделать ужин".

То, что вы покупаете у вас в качестве программиста, меньше строк кода и типа безопасности или позднего связывания. Например, пример с безопасностью типа и ранней привязкой (в c-подобном языке, который я составляю, когда я иду):

class BankAccount {
    void SubtractMonthlyFee
}

class CheckingAccount : BankAccount {}

class SavingsAccount : BankAccount {}

AssessFee(BankAccount acct) {
    // This will work for any class derived from
    //   BankAccount; even classes that don't exist yet
    acct.SubtractMonthlyFee
}

main() {

    CheckingAccount chkAcct;
    SavingsAccount saveAcct;

    // both lines will compile, because both accounts
    //   derive from "BankAccount". If you try to pass in
    //   an object that doesn't, it won't compile, EVEN
    //   if the object has a "SubtractMonthlyFee" method.
    AssessFee(chkAcct);
    AssessFee(saveAcct);
}

Вот пример без безопасности типа, но с поздним связыванием:

class DatabaseConnection {
    void ReleaseResources
}

class FileHandle {
    void ReleaseResources
}

FreeMemory(Object obj) {
    // This will work for any class that has a 
    //   "ReleaseResources" method (assuming all
    //   classes are ultimately derived from Object.
    obj.ReleaseResources
}

main() {

    DatabaseConnection dbConn;
    FileHandle fh;

    // You can pass in anything at all and it will
    //   compile just fine. But if you pass in an
    //   object that doesn't have a "ReleaseResources"
    //   method you'll get a run-time error.
    FreeMemory(dbConn);
    FreeMemory(fh);
    FreeMemory(acct); //FAIL! (but not until run-time)
}

В качестве отличного примера рассмотрим метод .NET ToString(). Все классы имеют это, потому что все классы производятся из класса Object. Но каждый класс может реализовать ToString() таким образом, который имеет смысл для себя.

EDIT: Простой!= короткий, IMHO

Ответ 15

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

Ответ 16

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

Ответ 17

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

Это делается путем обеспечения того, чтобы операции вызывали правильную реализацию для каждого типа данных. Даже в контексте ООП (в соответствии с этим тегом вопроса) эта "правильная реализация" может быть разрешена во время компиляции или времени выполнения (если ваш язык поддерживает оба). На некоторых языках, таких как С++, поддержка, предоставляемая компилятором для полиморфизма во время выполнения (т.е. виртуальная диспетчеризация), специфична для ООП, тогда как другие типы полиморфизма также могут работать с типами данных, которые не являются объектами (т.е. Не struct или class, но могут быть встроены в типы типа int или double).

(Типы поддержки полиморфизма С++ перечислены и сопоставлены в моем ответе: Полиморфизм в С++ - даже если вы программируете другие языки, это потенциально поучительно)

Ответ 18

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

interface IJobLoader

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

Возможно, я ушел.

Ответ 19

Термин полиморфизм также может применяться к функциям перегрузки. Например,

string MyFunc(ClassA anA);
string MyFunc(ClassB aB);

- это не объектно-ориентированный пример полиморфизма.

Ответ 20

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

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

foreach (Vehicle v in Game.Vehicles)
{
   v.Stop();
}

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

Ответ 21

Является ли способность объектам отвечать на одно и то же сообщение разными способами.

Например, на таких языках, как smalltalk, Ruby, Objective-C, вам просто нужно отправить сообщение, и они ответят.

 dao  = XmlDao.createNewInstance()    #obj 1
 dao.save( data )

 dao = RdbDao.createNewnewInstance()  #obj 2
 dao.save( data )

В этом примере два разных объекта ответили по-разному на одни и те же сообщения: "createNewInstance() и save (obj)"

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

В таких языках, как Java, С++, С# и т.д. Чтобы назначить объект объектной ссылке, они должны использовать одну и ту же иерархию типов либо путем реализации интерфейса, либо путем подкласса общего класса.

простой и простой.

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

Ответ 22

Это просто способ заставить старый холод вызвать новый код. Вы пишете приложение, которое принимает некоторый интерфейс "Shape" с методами, которые должны реализовать другие (пример - getArea). Если кто-то придумает новый способ whiz-bang реализовать этот интерфейс, ваш старый код может вызвать этот новый код с помощью метода getArea.

Ответ 23

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

Ответ 24

Полиморфизм - это объектно-ориентированное решение проблемы передачи функции другой функции. В C вы можете сделать

 void h() { float x=3.0; printf("%f", x); }
 void k() { int y=5; printf("%i", y); }
 void g(void (*f)()) { f(); }
 g(h);  // output 3.0
 g(k);  // output 5

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

 void h(void *a) { float* x=(float*)a; printf("%f",*x); }
 void k(void *a) { int* y=(int*)a; printf("%i",*y); }
 void g(void (*f)(void *a),void *a) { f(a); }
 float x=3.0;
 int y=5;
 g(h,&x); // output x
 g(k,&y); // output y

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

class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x