¿Qué es el polimorfismo, para qué sirve y cómo se usa?

564

¿Qué es el polimorfismo, para qué sirve y cómo se usa?

UnkwnTech
fuente
19
@ John: +1 Estoy de acuerdo en que es un fenómeno muy interesante. Estoy seguro de que Unkwntech no es la única persona conocedora y capaz de tener lagunas en lo que otros considerarían un vocabulario fundamental. Solo va a mostrar que la programación es un tema muy amplio.
AnthonyWJones
99
Podría usarlo, simplemente no darle un nombre.
Aiden Bell
10
@Aamir: No estoy seguro de que sea razonable suponer que alguien con 8k conocería todos los elementos fundamentales en todas las áreas de programación. Además, no creo que indique que el sistema de reputación es imperfecto. Alguien puede ganar una reputación considerable haciendo muchas buenas preguntas. Creo que nuestra respuesta natural a esta revelación simplemente demuestra que nosotros (los programadores) tenemos una tendencia natural a ser un poco estrechos (no es algo malo cuando necesitamos ser realmente buenos en un área técnica específica) y eso tiene sus desventajas.
AnthonyWJones
43
Ustedes parecen tener una visión muy limitada de la programación. Conozco muchachos que están haciendo un desarrollo integrado que no tienen conocimiento (o no necesitan) conceptos de OO en absoluto. Su objetivo es extraer hasta el último átomo de rendimiento del código y eso es todo: el código en el que están trabajando nunca entrará en el mundo de los objetos, y afortunadamente están lo suficientemente cerca del retiro como para no tener que preocuparse. aprendizaje de nuevos conceptos como el cuño objetos, polimorfismo y nombres de variables con más de dos letras :-)
paxdiablo
29
¿Cómo qué se aprende algo? Nadie vino a este mundo conociendo PHP OOP y patrones de diseño, por lo que todos ustedes en algún momento tuvieron que aprenderlo, en la universidad, una respuesta aquí, etc. No hablen de alguien "no se atrevieron a conocer procedimientos de código complejos ", y en cambio consideren que están aquí queriendo aprenderlo, lo cual es algo bueno y el objetivo de este sitio. Usa tu tiempo para ayudarlos, ya que estoy seguro de que te han ayudado en el pasado. Si a lo largo de la historia del hombre, en lugar de compartir conocimientos, la respuesta fuera "¿Qué? ¡Ja! ¿No lo sabes? ...", todos estaríamos en la Edad Media ...
James

Respuestas:

544

Si piensa en las raíces griegas del término, debería ser obvio.

  • Poli = muchos: polígono = muchos lados, poliestireno = muchos estirenos (a) , políglota = muchos idiomas, etc.
  • Morph = cambio o forma: morfología = estudio de la forma biológica, Morpheus = el dios griego de los sueños capaz de tomar cualquier forma.

Entonces, el polimorfismo es la capacidad (en programación) de presentar la misma interfaz para diferentes formas subyacentes (tipos de datos).

Por ejemplo, en muchos idiomas, los enteros y flotantes son implícitamente polimórficos, ya que puede sumar, restar, multiplicar, etc., independientemente del hecho de que los tipos son diferentes. Raramente se consideran objetos en el término habitual.

Sin embargo, en esa misma manera, una clase como BigDecimalo Rational, o Imaginarytambién puede proporcionar esas operaciones, a pesar de que operan en diferentes tipos de datos.

El ejemplo clásico es la Shapeclase y todas las clases que pueden heredar de ella (cuadrado, círculo, dodecaedro, polígono irregular, splat, etc.).

Con el polimorfismo, cada una de estas clases tendrá datos subyacentes diferentes. Una forma de punto solo necesita dos coordenadas (suponiendo que esté en un espacio bidimensional, por supuesto). Un círculo necesita un centro y radio. Un cuadrado o rectángulo necesita dos coordenadas para las esquinas superior izquierda e inferior derecha y (posiblemente) una rotación. Un polígono irregular necesita una serie de líneas.

Al hacer que la clase sea responsable de su código y de sus datos, puede lograr el polimorfismo. En este ejemplo, cada clase tendría su propia Draw()función y el código del cliente simplemente podría hacer:

shape.Draw()

para obtener el comportamiento correcto para cualquier forma.

Esto contrasta con la antigua forma de hacer cosas en las que el código estaba separado de los datos, y habría tenido funciones como drawSquare()y drawCircle().

La orientación a objetos, el polimorfismo y la herencia son conceptos estrechamente relacionados y son vitales para conocer. Ha habido muchas "balas de plata" durante mi larga carrera que básicamente fracasaron, pero el paradigma OO ha resultado ser bueno. Aprende, entiéndelo, ámalo, te alegrarás de haberlo hecho :-)


(a) Originalmente escribí eso como una broma, pero resultó ser correcto y, por lo tanto, no tan divertido. El monómero estireno está hecho de carbono e hidrógeno , y el poliestireno está hecho de grupos de eso .C8H8(C8H8)n

Tal vez debería haber dicho que un pólipo fue un hecho frecuente en la carta p, aunque ahora que he tenido que explicar el chiste, incluso eso tampoco parece gracioso.

A veces, deberías dejar de fumar mientras estás detrás :-)

paxdiablo
fuente
50
Griego, no latino :) (la 'y' y 'ph' son los regalos). Y en griego, 'morph-' es solo 'shape', o 'form' - el significado en inglés de ' change shape' para 'morph' es un desarrollo posterior
AakashM
16
El polimorfismo no está relacionado con la OOP, pero la OOP está relacionada con el polimorfismo porque es inherentemente compatible (suponiendo que es un lenguaje OOP decente). Mire FP para otros ejemplos de polimorfismo.
alternativa
99
Estas 2 líneas me Poly = many and Morph = change or form
ayudaron
3
Polyp es la abreviatura de polypo (u) s. Y pous es pie en griego. ;-)
Dirk
2
@Shaun, creo que puedes estar usando el término "interfaz" en un sentido demasiado literal / constrictivo: lo dije como un término en inglés en lugar de una definición específica de algún lenguaje informático arbitrario. No significa exactamente la misma función con exactamente los mismos parámetros, es simplemente una forma de afectar a los "objetos" de la misma manera, independientemente de su tipo concreto subyacente. Esto puede incluir la sobrecarga de métodos con diferentes tipos de parámetros, así como la forma más pura de polimorfismo.
paxdiablo
250

El polimorfismo es cuando puedes tratar un objeto como una versión genérica de algo, pero cuando accedes a él, el código determina qué tipo exacto es y llama al código asociado.

Aquí hay un ejemplo en C #. Cree cuatro clases dentro de una aplicación de consola:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

Ahora cree lo siguiente en el Main () del módulo para la aplicación de consola:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

En este ejemplo, creamos una lista de la clase base Vehículo, que no sabe cuántas ruedas tiene cada una de sus subclases, pero sí sabe que cada subclase es responsable de saber cuántas ruedas tiene.

Luego agregamos una bicicleta, automóvil y camión a la lista.

A continuación, podemos recorrer cada Vehículo en la lista y tratarlos a todos de manera idéntica, sin embargo, cuando accedemos a cada propiedad 'Ruedas' de los Vehículos, la clase Vehículo delega la ejecución de ese código a la subclase relevante.

Se dice que este código es polimórfico, ya que el código exacto que se ejecuta está determinado por la subclase a la que se hace referencia en tiempo de ejecución.

Espero que esto te ayude.

Antony Gibbs
fuente
66
Creo que este es un muy buen ejemplo para mostrar claramente la interfaz principal, y que no es hasta que se crea una instancia del objeto que se requiere una versión concreta, es decir, vehículo vs automóvil
cableado el
1
Diría que este es el ejemplo más claro, aunque si usted es un programador de PHP, este enlace podría ser más fácil de revisar PRIMERO, y luego mirar este después: code.tutsplus.com/tutorials/…
Oliver Williams
Además (más allá del alcance del OP) para notar que estamos restringiendo el análisis a objetos conocidos; no estamos pasando un objeto (como un archivo de importación) y luego determinamos de qué tipo es (Excel, CSV, YAML, SQL, etc., etc.). Para hacer esto, se necesitaría algún tipo de clase de fábrica para Class_Excel, Class_CSVser llamado o tener una Readerclase llamada. De cualquier manera, algún tipo de iterativo si / luego / otro va a tener que almacenarse en algún lugar.
Oliver Williams
@Antony Gibbs: este es un muy buen ejemplo (una lista de los tipos genéricos) que tiene sentido para mí ... de lo contrario, ¿cuál es el problema de que cada clase tenga su propia función de ruedas sin heredar de una clase base? ¿Hay más conceptos además de la lista que serían buenos para polimórficos?
TTT
195

De Comprender y aplicar el polimorfismo en PHP , gracias Steve Guidetti.

Polimorfismo es una palabra larga para un concepto muy simple.

El polimorfismo describe un patrón en la programación orientada a objetos en el que las clases tienen una funcionalidad diferente mientras comparten una interfaz común.

La belleza del polimorfismo es que el código que trabaja con las diferentes clases no necesita saber qué clase está usando, ya que todas se usan de la misma manera. Una analogía del mundo real para el polimorfismo es un botón. Todo el mundo sabe cómo usar un botón: simplemente le aplicas presión. Sin embargo, lo que un botón "hace" depende de a qué está conectado y al contexto en el que se usa, pero el resultado no afecta cómo se usa. Si su jefe le dice que presione un botón, ya tiene toda la información necesaria para realizar la tarea.

En el mundo de la programación, el polimorfismo se usa para hacer que las aplicaciones sean más modulares y extensibles. En lugar de declaraciones condicionales desordenadas que describen diferentes cursos de acción, crea objetos intercambiables que selecciona según sus necesidades. Ese es el objetivo básico del polimorfismo.

Ajay Patel
fuente
10
¿No se relaciona más la analogía del botón con el concepto de abstracción?
thewpfguy
66
Fuente original: code.tutsplus.com/tutorials/…
Alguien
8
@Mantriur: Esto de hecho está plagiado, y tenemos reglas en contra de eso: stackoverflow.com/help/referencing Pero dado su puntaje ahora y el hecho de que las publicaciones antiguas están exentas de pérdida de repeticiones en la eliminación de respuestas, no estoy seguro de si eliminarlas ahora directamente mejoraría cualquier cosa. La siguiente mejor alternativa sería simplemente editar en la atribución en nombre del usuario, aunque creo firmemente que los usuarios son responsables de citar fuentes en sus propias respuestas.
BoltClock
1
Creo que es incorrecto implicar que el polimorfismo es específico de las clases y / o la programación orientada a objetos, ya que el polimorfismo ad hoc o el polimorfismo paramétrico no requieren necesariamente clases u objetos. Creo que de lo que habla esta respuesta es del subtipo (también conocido como polimorfismo de subtipo o polimorfismo de inclusión).
StubbornShowaGuy
64

Si alguien dice CORTE a estas personas

  1. El cirujano
  2. El estilista
  3. El actor

¿Lo que sucederá?

  • El cirujano comenzaría a hacer una incisión.
  • El estilista comenzaría a cortar el cabello de alguien.
  • El actor dejaría de actuar abruptamente fuera de la escena actual, esperando la dirección del director.

Entonces, la representación anterior muestra qué es el polimorfismo (mismo nombre, comportamiento diferente) en OOP.

Si vas a una entrevista y el entrevistador te pide que digas / muestres un ejemplo en vivo de polimorfismo en la misma habitación en la que estamos sentados, di-

Respuesta: puerta / ventanas

¿Se pregunta cómo?

A través de la puerta / ventana: puede venir una persona, puede llegar el aire, puede venir la luz, puede venir la lluvia, etc.

Para entenderlo mejor y de manera simple, utilicé el ejemplo anterior. Si necesita una referencia para el código, siga las respuestas anteriores.

Sanchit
fuente
55
No creo que este sea un gran ejemplo porque puede hacer que personas sin experiencia piensen que si dos clases tienen un .foo()método, entonces deberían compartir una interfaz común. Sin embargo, esto no es cierto y conduce a abstracciones incorrectas. Una interfaz debe definir un rol que se debe jugar, que puede tener muchas implementaciones diferentes, pero todas se extraen del mismo conjunto de entrada y devuelven algo del mismo conjunto de salida. La entrada x.cut(...)para un cirujano, estilista o actor no es la misma, y ​​tampoco lo es la salida.
Matt Klein
38

Explicación simple por analogía

El presidente de los Estados Unidos emplea polimorfismo. ¿Cómo? Bueno, él tiene muchos asesores:

  1. Consejeros militares
  2. Asesores legales
  3. Físicos nucleares (como asesores)
  4. Consejeros medicos
  5. etcétera etcétera.

Todos deberían ser responsables de una sola cosa: Ejemplo:

El presidente no es un experto en revestimiento de zinc o física cuántica. No sabe muchas cosas, pero solo sabe una: cómo manejar el país.

Es lo mismo con el código: las preocupaciones y las responsabilidades deben separarse de las clases / personas relevantes. De lo contrario, haría que el presidente supiera literalmente todo en el mundo: toda la Wikipedia. Imagine tener toda la wikipedia en una clase de su código: sería una pesadilla mantenerla.

¿Por qué es una mala idea que un presidente sepa todas estas cosas específicas?

Si el presidente le dijera específicamente a la gente qué hacer, eso significaría que el presidente necesita saber exactamente qué hacer. Si el presidente necesita saber cosas específicas por sí mismo, eso significa que cuando necesite hacer un cambio, deberá hacerlo en dos lugares, no solo en uno.

Por ejemplo, si la EPA cambia las leyes de contaminación, cuando eso suceda: tendría que hacer un cambio en la Clase EPA y también en la clase Presidente. Cambiar el código en dos lugares en lugar de uno puede ser peligroso, porque es mucho más difícil de mantener.

¿Hay un mejor enfoque?

Hay un mejor enfoque: el presidente no necesita conocer los detalles de nada: puede exigir el mejor consejo de personas específicamente encargadas de hacer esas cosas.

Puede usar un enfoque polimórfico para dirigir el país.

Ejemplo - de usar un enfoque polimórfico:

Todo lo que el presidente hace es pedirle a la gente que lo asesore, y eso es lo que realmente hace en la vida real, y eso es lo que debe hacer un buen presidente. todos sus asesores responden de manera diferente, pero todos saben lo que quiere decir el presidente con: Asesorar (). Tiene cientos de personas entrando en su oficina. En realidad no importa quiénes son. Todo lo que el presidente sabe es que cuando les pide que "aconsejen", saben cómo responder en consecuencia :

public class MisterPresident
{
    public void RunTheCountry()
    {
        // assume the Petraeus and Condi classes etc are instantiated.
        petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
        condolezza.Advise(); // # she says negotiate trade deal with Iran
        healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
    }
}

Este enfoque le permite al presidente dirigir el país literalmente sin saber nada sobre asuntos militares, ni sobre atención médica o diplomacia internacional: los detalles se dejan a los expertos. Lo único que el presidente necesita saber es esto: "Aconsejar ()".

Lo que NO quieres:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // people walk into the Presidents office and he tells them what to do
        // depending on who they are.

        // Fallujah Advice - Mr Prez tells his military exactly what to do.
        petraeus.IncreaseTroopNumbers();
        petraeus.ImproveSecurity();
        petraeus.PayContractors();

        // Condi diplomacy advice - Prez tells Condi how to negotiate

        condi.StallNegotiations();
        condi.LowBallFigure();
        condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();

        // Health care

        healthOfficial.IncreasePremiums();
        healthOfficial.AddPreexistingConditions();
    }
}

¡NO! ¡NO! ¡NO! En el escenario anterior, el presidente está haciendo todo el trabajo: sabe sobre el aumento del número de tropas y las condiciones preexistentes. Esto significa que si las políticas de Oriente Medio cambian, entonces el presidente tendría que cambiar sus comandos, así como también la clase de Petraeus. Solo deberíamos tener que cambiar la clase de Petraeus, porque el presidente no debería verse empantanado en ese tipo de detalles. No necesita saber sobre los detalles. Todo lo que necesita saber es que si hace un pedido, todo se encargará. Todos los detalles deben dejarse a los expertos.

Esto le permite al presidente hacer lo que mejor sabe hacer: establecer una política general, verse bien y jugar golf: P.

¿Cómo se implementa realmente? A través de una clase base o una interfaz común

Eso en efecto es polimorfismo, en pocas palabras. ¿Cómo se hace exactamente? Mediante la "implementación de una interfaz común" o mediante el uso de una clase base (herencia), vea las respuestas anteriores que detallan esto más claramente. (Para comprender más claramente este concepto, necesita saber qué es una interfaz, y deberá comprender qué es la herencia. Sin eso, podría tener dificultades).

En otras palabras, Petraeus, Condi y HealthOfficials todo habría clases que "implementen una interfaz" - llamada hagámosle la IAdvisorinterfaz que solo contiene un método: Advise(). Pero ahora nos estamos adentrando en los detalles.

Esto seria ideal

    public class MisterPresident
    {
            // You can pass in any advisor: Condi, HealthOfficials,
            //  Petraeus etc. The president has no idea who it will 
            // be. But he does know that he can ask them to "advise" 
            // and that's all Mr Prez cares for.

        public void RunTheCountry(IAdvisor governmentOfficer)
        {             
            governmentOfficer.Advise();              
        }
    }


    public class USA
    {
        MisterPresident president;

        public USA(MisterPresident president)
        {
            this.president = president;
        }

        public void ImplementPolicy()
        {
            IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
            president.RunTheCountry(governmentOfficer);
        }
    }

Resumen

Todo lo que realmente necesitas saber es esto:

  • El presidente no necesita conocer los detalles, estos se dejan a otros.
  • Todo lo que el presidente necesita saber es preguntar quién entra por la puerta para asesorarlo, y sabemos que sabrán absolutamente qué hacer cuando se les pida que asesoren (porque en realidad son asesores (o IAdvisors :))

Realmente espero que te ayude. Si no comprende nada, publique un comentario e intentaré nuevamente.

BKSpurgeon
fuente
44
Fantástico ejemplo! Gracias.
Iman Sedighi
1
Muy interesante analogía. Gracias.
thanhtang
1
@TTT porque (1) cada vez que tiene un nuevo asesor, entonces tendría que cambiar la clase de presidente; no desea realizar cambios x2. solo uno. (2) en segundo lugar, si tiene que cambiar un asesor existente, entonces puede que tenga que regresar y cambiar una de esas tres llamadas en la clase de presidente; solo desea hacer un cambio, no dos. (3) si tuviera tres llamadas separadas, entonces tendría que preguntar, dentro de la clase de presidente: if healthAdvisor? then do this:y if petraus then do that etc.este patrón deberá repetirse y eso es innecesario y complicado. ver arriba editar.
BKSpurgeon el
1
@TTT sí, tienes razón. pero tengo que presentar lentamente el concepto a los lectores, de lo contrario no lo entenderán. He agregado más cambios. avise si necesita aclaraciones
BKSpurgeon
1
@TTT clase base vs interfaz es una decisión de diseño que los programadores deben tomar al hacer polimorpismo. ver aquí para más detalles: stackoverflow.com/questions/56867/interface-vs-base-class
BKSpurgeon
24

El polimorfismo es la capacidad de tratar una clase de objeto como si fuera la clase principal.

Por ejemplo, supongamos que hay una clase llamada Animal, y una clase llamada Perro que hereda de Animal. El polimorfismo es la capacidad de tratar cualquier objeto Perro como un objeto Animal de esta manera:

Dog* dog = new Dog;
Animal* animal = dog;
Tom Dalling
fuente
Me pregunto cómo se relaciona esto con la explicación (popular) que @Ajay Patel dioclasses have different functionality while sharing a common interface
BornToCode
1
@BornToCode La clase padre es / proporciona esa interfaz común.
grokmann
1
El polimorfismo no requiere subtipificación.
Shaun Luttin
22

Polimorfismo:

Es el concepto de programación orientada a objetos. La capacidad de diferentes objetos para responder, cada uno a su manera, a mensajes idénticos se llama polimorfismo.

El polimorfismo resulta del hecho de que cada clase vive en su propio espacio de nombres. Los nombres asignados dentro de una definición de clase no entran en conflicto con los nombres asignados en cualquier lugar fuera de ella. Esto es cierto tanto para las variables de instancia en la estructura de datos de un objeto como para los métodos del objeto:

  • Así como los campos de una estructura C están en un espacio de nombres protegido, también lo están las variables de instancia de un objeto.

  • Los nombres de los métodos también están protegidos. A diferencia de los nombres de las funciones C, los nombres de los métodos no son símbolos globales. El nombre de un método en una clase no puede entrar en conflicto con los nombres de métodos en otras clases; dos clases muy diferentes pueden implementar métodos con nombres idénticos.

Los nombres de los métodos son parte de la interfaz de un objeto. Cuando se envía un mensaje solicitando que un objeto haga algo, el mensaje nombra el método que debe realizar el objeto. Debido a que diferentes objetos pueden tener métodos con el mismo nombre, el significado de un mensaje debe entenderse en relación con el objeto particular que recibe el mensaje. El mismo mensaje enviado a dos objetos diferentes puede invocar dos métodos distintos.

El principal beneficio del polimorfismo es que simplifica la interfaz de programación. Permite establecer convenciones que se pueden reutilizar en clase tras clase. En lugar de inventar un nuevo nombre para cada nueva función que agregue a un programa, se pueden reutilizar los mismos nombres. La interfaz de programación puede describirse como un conjunto de comportamientos abstractos, aparte de las clases que los implementan.

Ejemplos:

Ejemplo-1: Este es un ejemplo sencillo escrito en Python 2.x .

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

Ejemplo 2: El polimorfismo se implementa en Java utilizando la sobrecarga de métodos y los conceptos de anulación de métodos .

Consideremos el ejemplo de Car para discutir el polimorfismo. Tome cualquier marca como Ford, Honda, Toyota, BMW, Benz, etc., todo es de tipo automóvil.

Pero cada uno tiene sus propias características avanzadas y tecnología más avanzada involucrada en su comportamiento de movimiento.

Ahora vamos a crear un tipo básico de coche

Car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

Implementemos el ejemplo de Ford Car.

Ford extiende el tipo Car para heredar todos sus miembros (propiedades y métodos).

Ford.java

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

La clase Ford anterior amplía la clase Car y también implementa el método move (). A pesar de que el método de movimiento ya está disponible para Ford a través de la Herencia, Ford aún lo ha implementado a su manera. Esto se llama anulación de método.

Honda.java

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

Al igual que Ford, Honda también extiende el tipo de automóvil e implementa el método de movimiento a su manera.

La anulación del método es una característica importante para habilitar el polimorfismo. Usando la anulación de métodos, los tipos Sub pueden cambiar la forma en que funcionan los métodos que están disponibles a través de la herencia.

PolymorphismExample.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

Salida de ejemplo de polimorfismo:

En el método principal de la clase PolymorphismExample, he creado tres objetos: Car, Ford y Honda. Los tres objetos se refieren por el tipo de automóvil.

Tenga en cuenta un punto importante aquí que un tipo de superclase puede referirse a un tipo de objeto de subclase, pero el viceversa no es posible. La razón es que todos los miembros de la superclase están disponibles para la subclase usando herencia y durante el tiempo de compilación, el compilador intenta evaluar si el tipo de referencia que estamos usando tiene el método al que está intentando acceder.

Entonces, para las referencias car, f y h en el Ejemplo de polimorfismo, el método de movimiento existe desde el tipo Car. Entonces, el compilador pasa el proceso de compilación sin ningún problema.

Pero cuando se trata de la ejecución en tiempo de ejecución, la máquina virtual invoca los métodos en los objetos que son subtipos. Entonces, el método move () se invoca desde sus respectivas implementaciones.

Por lo tanto, todos los objetos son del tipo Car, pero durante el tiempo de ejecución, la ejecución depende del objeto en el que se realiza la invocación. Esto se llama polimorfismo.

Tony Stark
fuente
El concepto de sobrecarga no tiene nada que ver con la herencia y el polimorfismo.
srk
La sobrecarga del método @srk es una forma de implementar el polimorfismo. A menudo se clasifica como polimorfismo estático o ad hoc. wiki.c2.com/?CategoryPolymorphism
Shaun Luttin
12

Por lo general, esto se refiere a la capacidad de un objeto de tipo A de comportarse como un objeto de tipo B. En la programación orientada a objetos, esto generalmente se logra por herencia. Algunos enlaces de wikipedia para leer más:

EDITAR: enlaces rotos fijos.

JesperE
fuente
10
"la capacidad de un objeto de tipo A para comportarse como un objeto de tipo B" - no es una definición precisa. Yo diría que es más como la capacidad para tratar un objeto de tipo A como si fuera un objeto de tipo B.
Artem Barger
Si. Tal vez esa sea una mejor redacción.
JesperE
Para completar, muchos idiomas implementan el polimorfismo a través de la tipificación de pato, por ejemplo, Python.
ilya n.
Me pregunto cómo se relaciona esto con la explicación (popular) que dio @Ajay Patelclasses have different functionality while sharing a common interface
BornToCode
9

El polimorfismo es este:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

puedes pasar solo una Copa en lugar de una instancia específica. Esto ayuda en general porque no tiene que proporcionar una instancia de measure () específica para cada tipo de taza

Vinko Vrsalovic
fuente
2
Este es específicamente un subtipo de polimorfismo.
Shaun Luttin
@ vinko-vrsalovic: ¿cómo es el desarrollo de software en la América rural?
TTT
8

Sé que esta es una pregunta anterior con muchas buenas respuestas, pero me gustaría incluir una respuesta de una oración:

Tratar un tipo derivado como si fuera su tipo base.

Hay muchos ejemplos anteriores que muestran esto en acción, pero creo que esta es una buena respuesta concisa.

Abe Miessler
fuente
2
Este es un subtipo, que es solo un tipo de polimorfismo.
Shaun Luttin
@ShaunLuttin, ¿puede indicarme algún recurso para obtener más información sobre los otros tipos de polimorfismo?
Abe Miessler
Son "polimorfismo ad hoc" y "polimorfismo paramétrico" además del "polimorfismo de subtipo".
Shaun Luttin el
8

(Estaba leyendo otro artículo sobre algo completamente diferente ... y apareció el polimorfismo ... Ahora pensé que sabía lo que era el Polimorfismo ... pero aparentemente no de esta hermosa manera explicada ... Quería escribirlo en alguna parte ... mejor aún lo compartiré ...)

http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife

sigue leyendo de esta parte:

..... polimorfismo. Esa es una manera geek de decir que a diferentes sustantivos se les puede aplicar el mismo verbo.

Kcats Wolfrevo
fuente
5

En términos generales, es la capacidad de interactuar con varios tipos diferentes de objetos utilizando la misma API o una API superficialmente similar. Hay varias formas:

  • Sobrecarga de funciones: definición de múltiples funciones con el mismo nombre y diferentes tipos de parámetros, como sqrt (float), sqrt (double) y sqrt (complex). En la mayoría de los idiomas que permiten esto, el compilador seleccionará automáticamente el correcto para el tipo de argumento que se le pasa, por lo tanto, este es un polimorfismo en tiempo de compilación.

  • Métodos virtuales en OOP: un método de una clase puede tener varias implementaciones adaptadas a los detalles de sus subclases; Se dice que cada uno de ellos anula la implementación dada en la clase base. Dado un objeto que puede ser de la clase base o cualquiera de sus subclases, la implementación correcta se selecciona sobre la marcha, por lo tanto, este es el polimorfismo en tiempo de ejecución.

  • Plantillas: una característica de algunos lenguajes OO mediante la cual una función, clase, etc. se puede parametrizar por tipo. Por ejemplo, puede definir una clase de plantilla genérica "lista", y luego crear una instancia como "lista de enteros", "lista de cadenas", tal vez incluso "lista de listas de cadenas" o similares. Generalmente, escribe el código una vez para una estructura de datos de tipo de elemento arbitrario, y el compilador genera versiones de él para los distintos tipos de elementos.

Stewart
fuente
4

El término polimorfismo proviene de:

poli = muchos

morfismo = la capacidad de cambiar

En programación, el polimorfismo es una "técnica" que le permite "mirar" un objeto como si fuera más de un tipo de cosa. Por ejemplo:

Un objeto de estudiante también es un objeto de persona. Si "mira" (es decir, el elenco) al estudiante, probablemente pueda solicitar la identificación del estudiante. No siempre se puede hacer eso con una persona, ¿verdad? (una persona no es necesariamente un estudiante, por lo tanto, podría no tener una identificación de estudiante). Sin embargo, una persona probablemente tiene un nombre. Un estudiante también lo hace.

En pocas palabras, "mirar" el mismo objeto desde diferentes "ángulos" puede darle diferentes "perspectivas" (es decir, diferentes propiedades o métodos)

Entonces, esta técnica le permite construir cosas que se pueden "mirar" desde diferentes ángulos.

¿Por qué usamos polimorfismo? Para empezar ... abstracción. En este punto, debería ser suficiente información :)

tzup
fuente
3

Usemos una analogía. Para un guión musical dado, cada músico que lo toca le da su propio toque en la interpretación.

El músico puede abstraerse con interfaces, el género al que pertenece el músico puede ser una clase abstracta que define algunas reglas globales de interpretación y cada músico que toca puede modelarse con una clase concreta.

Si eres un oyente del trabajo musical, tienes una referencia al guión, por ejemplo, 'Fuga and Tocata' de Bach, y cada músico que lo interpreta lo hace polimórficamente a su manera.

Este es solo un ejemplo de un posible diseño (en Java):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}
Boris Pavlović
fuente
1
AnnHallowayy VictorBorgasienta que deberían ser objetos en lugar de clases; su ejemplo se leería mejor con, por ejemplo, public class Pianist implements Musiciany victorBorge = new Pianist();etc.
Przemek D
3

He proporcionado una descripción general de alto nivel del polimorfismo para otra pregunta:

Polimorfismo en c ++

Espero eso ayude. Un extracto...

... ayuda comenzar con una prueba simple y la definición de [polimorfismo]. Considera el código:

Type1 x;
Type2 y;

f(x);
f(y);

Aquí, f()es realizar alguna operación y se le están dando los valores xy ycomo entradas. Para ser polimórfico, f()debe ser capaz de operar con valores de al menos dos tipos distintos (por ejemplo, inty double), encontrando y ejecutando código apropiado para cada tipo.

(continúa en Polimorfismo en c ++ )

Tony Delroy
fuente
3

El polimorfismo es una habilidad del objeto que puede tomarse de muchas formas. Por ejemplo, en la clase humana, un hombre puede actuar de muchas formas cuando hablamos de relaciones. EX: Un hombre es padre de su hijo y él es esposo de su esposa y él es maestro de sus alumnos.

Rohit
fuente
3

El polimorfismo es la capacidad de un objeto de adoptar muchas formas. El uso más común del polimorfismo en OOP se produce cuando una referencia de clase primaria se usa para referirse a un objeto de clase secundaria. En este ejemplo que está escrito en Java, tenemos tres tipos de vehículos. Creamos tres objetos diferentes e intentamos ejecutar su método de ruedas:

public class PolymorphismExample {

    public static abstract class Vehicle
    {
        public int wheels(){
            return 0;
        }
    }

    public static class Bike extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 2;
        }
    }

    public static class Car extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 4;
        }
    }

    public static class Truck extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 18;
        }
    }

    public static void main(String[] args)
    {
        Vehicle bike = new Bike();
        Vehicle car = new Car();
        Vehicle truck = new Truck();

        System.out.println("Bike has "+bike.wheels()+" wheels");
        System.out.println("Car has "+car.wheels()+" wheels");
        System.out.println("Truck has "+truck.wheels()+" wheels");
    }

}

El resultado es:

El resultado

Para obtener más información, visite https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/PolymorphismExample.java . Espero que ayude.

Mohammad
fuente
Sí, pero no explicaste cuáles son los beneficios del polimorfismo. Obviamente, hay un código más corto, donde eliminaría la clase Vehículo, y aún funcionaría (con una declaración de objeto diferente, por supuesto).
Cornelius
No lo expliqué, ya que la persona que hizo la pregunta no preguntó por los beneficios. Él preguntó: "¿Qué es el polimorfismo, para qué sirve y cómo se usa?". Sobre el código, si puede hacerlo mejor, publique su respuesta. Entonces, nuestra comunidad puede usarlo. Gracias por tu comentario.
Mohammad
Lo siento, no quería sonar grosero, otros no lo explicaron también. Al menos te molestaste en escribir el código. De todos modos, preguntó para qué sirve, pero ninguno de los ejemplos en esta página explica para qué sirve. Todos ustedes presentan una forma compleja de obtener los mismos resultados que esto: s28.postimg.org/jq8vl6031/Poly.jpg y ninguno se preocupó por explicar por qué uno querría usar el polimorfismo, cuál es su ganancia o propósito, qué podría no haber sido hecho si no fue utilizado? Todo lo que veo en esta página es una propuesta para subir a su apartamento usando escaleras, y no un elevador ...
Cornelius
.. sin notar que uno lleva un asta de bandera que es demasiado grande para caber en un elevador. No sé cómo publicar código, así que no puedo ser de mucha ayuda ...
Cornelius
2

El polimorfismo es la capacidad del programador para escribir métodos del mismo nombre que hacen cosas diferentes para diferentes tipos de objetos, dependiendo de las necesidades de esos objetos. Por ejemplo, si estaba desarrollando una clase llamada Fractiony una clase llamada ComplexNumber, ambos podrían incluir un método llamado display(), pero cada uno de ellos implementaría ese método de manera diferente. En PHP, por ejemplo, puede implementarlo así:

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

Salidas:

This is a fraction: 1/2
This is a complex number: 1 + 2i

Algunas de las otras respuestas parecen implicar que el polimorfismo se usa solo junto con la herencia; por ejemplo, quizás Fractiony ComplexNumberambos implementan una clase abstracta llamada Numberque tiene un método display(), que Fraction y ComplexNumber están obligados a implementar. Pero no necesitas herencia para aprovechar el polimorfismo.

Al menos en lenguajes de tipo dinámico como PHP (no sé acerca de C ++ o Java), el polimorfismo permite al desarrollador llamar a un método sin necesariamente conocer el tipo de objeto con anticipación, y confiando en que la implementación correcta del método ser llamado. Por ejemplo, supongamos que el usuario elige el tipo de Numbercreado:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

En este caso, display()se llamará al método apropiado , aunque el desarrollador no pueda saber de antemano si el usuario elegirá una fracción o un número complejo.

Alex Basson
fuente
2
Eso no es polimorfismo. Son dos clases que tienen métodos del mismo nombre. Tendrían que estar vinculados por una clase base o interfaz llamada "visualizable" o algo similar, y luego otros métodos simplemente se preocuparían de que el objeto sea del tipo "visualizable" en lugar de Complejo o Fracción.
Pod
Siempre pensé que el polimorfismo era "dos clases que tienen métodos del mismo nombre". De hecho, para citar a Stephan Kochan (de quien soy desvergonzado estafando este ejemplo de Fracción / Complejo), "la capacidad de compartir el mismo nombre de método en diferentes clases se conoce como polimorfismo". (de Programming_In_Objective-C ) No menciona ninguna necesidad de vincular clases a través de una clase base. Tal vez es diferente en diferentes idiomas, honestamente no lo sé.
Alex Basson
Incluso si esta defensa se cita en un libro publicado, aún argumentaría que es incorrecta. Especialmente porque parece chocar entre sí, la defensa agnóstica del lenguaje del polimorfismo. Y si bien el resultado final es el mismo que se observa con el polimorfismo, yo diría que, en cambio, es la tipificación dinámica lo que permite al programador ser capaz de impulsar que se llame a la implementación correcta de un método entre otros métodos con nombres similares.
vipirtti
2

En la programación orientada a objetos, el polimorfismo se refiere a la capacidad de un lenguaje de programación para procesar objetos de manera diferente dependiendo de su tipo de datos o clase . Más específicamente, es la capacidad de redefinir métodos para clases derivadas.

sjith
fuente
2

El polimorfismo significa literalmente formas múltiples. (o muchas formas): objeto de diferentes clases y el mismo método de nombre, pero los flujos de trabajo son diferentes. Un ejemplo simple sería:

Considere a una persona X.

Él es solo una persona, pero actúa como muchos. Puede preguntar cómo:

Él es un hijo para su madre. Un amigo para sus amigos. Un hermano para su hermana.

Shourob Datta
fuente
2

El polimorfismo en OOP significa que una clase podría tener diferentes tipos, la herencia es una forma de implementar el polimorfismo.

por ejemplo, Shape es una interfaz, tiene subtipos Square , Circle , Diamond . ahora que tiene un objeto Cuadrado, puede convertir Cuadrado en Forma automáticamente, porque Cuadrado es una Forma. Pero cuando intentas reducir Shape a Square, debes hacer una conversión de tipo explícita, porque no puedes decir que Shape es Square, también podría ser Circle. por lo que debe emitirlo manualmente con un código como Square s = (Square)shape, lo que si la forma es Circle, obtendrá java.lang.ClassCastException, porque Circle no es Square.

Frank Zhang
fuente
2

Polimorfismo:

Ejecución diferente según la instancia de la clase, no el tipo de variable de referencia.

Una variable de referencia de tipo de interfaz puede hacer referencia a cualquiera de las instancias de clase que implementan esa interfaz.

Hassan Tareq
fuente
1

El polimorfismo es la capacidad de usar un objeto en una clase dada, donde todos los componentes que componen el objeto son heredados por las subclases de la clase dada. Esto significa que una vez que una clase declara este objeto, todas las subclases debajo de él (y sus subclases, y así sucesivamente hasta llegar a la subclase más lejana / más baja) heredan el objeto y sus componentes (composición).

Recuerde que cada clase debe guardarse en archivos separados.

El siguiente código ejemplifica el polimorfismo:

La superclase:

public class Parent {
    //Define things that all classes share
    String maidenName;
    String familyTree;

    //Give the top class a default method
    public void speak(){
         System.out.println("We are all Parents");
    }
}

El padre, una subclase:

public class Father extends Parent{
    //Can use maidenName and familyTree here
    String name="Joe";
    String called="dad";

    //Give the top class a default method
    public void speak(){
        System.out.println("I am "+name+", the father.");
    }
}

El niño, otra subclase:

public class Child extends Father {
    //Can use maidenName, familyTree, called and name here

    //Give the top class a default method
    public void speak(){
        System.out.println("Hi "+called+". What are we going to do today?");
    }
}

El método de ejecución hace referencia a la clase Parent para comenzar:

public class Parenting{
    public static void main(String[] args) {
        Parent parents = new Parent();
        Parent parent = new Father();
        Parent child = new Child();

        parents.speak();
        parent.speak();
        child.speak();
    }
}

Tenga en cuenta que cada clase debe declararse en archivos * .java separados. El código debe compilarse. También tenga en cuenta que puede usar continuamente maidenName y familyTree más abajo. Ese es el concepto de polimorfismo. El concepto de herencia también se explora aquí, donde se puede usar una clase o se define con más detalle por una subclase.

Espero que esto ayude y lo deje claro. Publicaré los resultados cuando encuentre una computadora que pueda usar para verificar el código. Gracias por la paciencia!

Midimistro
fuente
2
tenga en cuenta que cada niño no es un padre, por lo que esta estructura es incorrecta. La clase superior debería ser Child (si no solo está comenzando con "Person"), lo que siempre será cierto, excepto Adam. Puede establecer su parent_id en nulo ya que el Creador no se puede definir con ninguna construcción de intelecto humano.
Yehosef el
1

El polimorfismo permite que la misma rutina (función, método) actúe sobre diferentes tipos.

Dado que muchas respuestas existentes combinan el subtipo con el polimorfismo, aquí hay tres formas (incluido el subtipo) para implementar el polimorfismo.

  • El polimorfismo paramétrico (genérico) permite que una rutina acepte uno o más parámetros de tipo, además de los parámetros normales, y se ejecuta en esos tipos.
  • Subtipo de polimorfismo permite que una rutina actúe sobre cualquier subtipo de sus parámetros.
  • El polimorfismo ad hoc generalmente usa una sobrecarga de rutina para garantizar un comportamiento polimórfico, pero también puede referirse a otras implementaciones de polimorfismo.

Ver también:

http://wiki.c2.com/?CategoryPolymorphism

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

Shaun Luttin
fuente
0

En lenguajes orientados a objetos, el polimorfismo permite el tratamiento y manejo de diferentes tipos de datos a través de la misma interfaz. Por ejemplo, considere la herencia en C ++: la clase B se deriva de la clase A. Se puede usar un puntero de tipo A * (puntero a la clase A) para manejar tanto un objeto de clase A como un objeto de clase B.

Eran Rehavi
fuente
0

El polimorfismo en términos de codificación es cuando su objeto puede existir como múltiples tipos a través de la herencia, etc. Si crea una clase llamada "Forma" que define el número de lados que tiene su objeto, puede crear una nueva clase que lo herede, como "Cuadrado ". Cuando posteriormente realice una instancia de "Cuadrado", puede lanzarlo hacia atrás y hacia adelante desde "Forma" a "Cuadrado" según sea necesario.

Brian Scott
fuente
0

El polimorfismo le brinda la capacidad de crear un módulo que llama a otro y, sin embargo, tiene el punto de dependencia del tiempo de compilación contra el flujo de control en lugar de hacerlo con el flujo de control.

Al usar polimorfismo, un módulo de alto nivel no depende del módulo de bajo nivel. Ambos dependen de abstracciones. Esto nos ayuda a aplicar el principio de inversión de dependencia ( https://en.wikipedia.org/wiki/Dependency_inversion_principle ).

Aquí es donde encontré la definición anterior. Alrededor de 50 minutos en el video, el instructor explica lo anterior. https://www.youtube.com/watch?v=TMuno5RZNeE

Raghav Navada
fuente
0

¿Qué es el polimorfismo?

El polimorfismo es la capacidad de:

  • Invoque una operación en una instancia de un tipo especializado solo conociendo su tipo generalizado mientras llama al método del tipo especializado y no al del tipo generalizado: es polimorfismo dinámico .

  • Defina varios métodos que tengan el nombre de guardar pero que tengan diferentes parámetros: es polimorfismo estático .

La primera si la definición histórica y la más importante.

¿Para qué se usa el polimorfismo?

Permite crear una consistencia fuertemente tipada de la jerarquía de clases y hacer algunas cosas mágicas como administrar listas de objetos de diferentes tipos sin conocer sus tipos pero solo uno de sus tipos principales, así como los enlaces de datos.

Mecanografía fuerte y débil

Muestra

Aquí hay algunas formas como Punto, Línea, Rectángulo y Círculo que tienen la operación Draw () que no toma nada o un parámetro para establecer un tiempo de espera para borrarlo.

public class Shape
{
 public virtual void Draw()
 {
   DoNothing();
 }
 public virtual void Draw(int timeout)
 {
   DoNothing();
 }
}

public class Point : Shape
{
 int X, Y;
 public override void Draw()
 {
   DrawThePoint();
 }
}

public class Line : Point
{
 int Xend, Yend;
 public override Draw()
 {
   DrawTheLine();
 }
}

public class Rectangle : Line
{
 public override Draw()
 {
   DrawTheRectangle();
 }
}

var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };

foreach ( var shape in shapes )
  shape.Draw();

Aquí la clase Shape y los métodos Shape.Draw () deben marcarse como abstractos.

No son para hacer entender.

Explicación

Sin polimorfismo, usando abstract-virtual-override, mientras analiza las formas, solo se llama al método Spahe.Draw () ya que CLR no sabe a qué método llamar. Entonces llama al método del tipo sobre el que actuamos, y aquí el tipo es Shape debido a la declaración de la lista. Entonces el código no hace nada en absoluto.

Con el polimorfismo, el CLR puede inferir el tipo real del objeto sobre el que actuamos utilizando lo que se llama una tabla virtual. Entonces llama a lo bueno método, y aquí llamando a Shape.Draw () si Shape es Point llama a Point.Draw (). Entonces el código dibuja las formas.

Más lecturas

C # - Polimorfismo (Nivel 1)

Polimorfismo en Java (Nivel 2)

Polimorfismo (Guía de programación de C #)

Tabla de método virtual

Olivier Rogier
fuente