¿Cuál es la diferencia entre polimorfismo dinámico y estático en Java?

118

¿Alguien puede proporcionar un ejemplo simple que explique la diferencia entre el polimorfismo dinámico y estático en Java?

Prabhakar Manthena
fuente
4
Las anulaciones a veces se denominan "polimorfismo estático". Esto estira un poco las cosas, pero eso es lo que está sucediendo.
dasblinkenlight
@dasblinkenlight gracias por la información. ¿hay algún ejemplo de eso?
Prabhakar Manthena
Busque "sobrecarga de método" y "anulación de método".
dasblinkenlight
5
No entiendo cómo la sobrecarga es el polimorfismo. El polimorfismo es un concepto de objeto. deberíamos poder mostrar el objeto B como el objeto A. del ejemplo siguiente (respuesta) mostraste Perro como animal y, por lo tanto, es polimorfismo. Pero en la sobrecarga está llamando a un método diferente pero con el "mismo nombre". ¿Cómo puede esto ser polimorfismo? Por lo tanto, "unión estática" es el término correcto para usar, pero el polimorfismo estático no lo es en caso de sobrecarga.
Punith Raj
@PunithRaj Probablemente se esté refiriendo al polimorfismo de subtipo . Hay otro tipo llamado Ad hoc que se aplica a la sobrecarga.
Kelvin

Respuestas:

196

Polimorfismo

1. Enlace estático / Enlace en tiempo de compilación / Enlace anticipado / Sobrecarga de método (en la misma clase)

2. Enlace dinámico / Enlace en tiempo de ejecución / Enlace tardío / Anulación de método (en diferentes clases)

ejemplo de sobrecarga:

class Calculation {  
  void sum(int a,int b){System.out.println(a+b);}  
  void sum(int a,int b,int c){System.out.println(a+b+c);}  

  public static void main(String args[]) {  
    Calculation obj=new Calculation();  
    obj.sum(10,10,10);  // 30
    obj.sum(20,20);     //40 
  }  
}  

ejemplo primordial:

class Animal {    
   public void move(){
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {

   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal(); // Animal reference and object
      Animal b = new Dog(); // Animal reference but Dog object

      a.move();//output: Animals can move

      b.move();//output:Dogs can walk and run
   }
}
KhAn SaAb
fuente
6
Soy nuevo en Java, así que solo curiosidad, ¿cuál es el concepto subyacente entre Animal reference but Dog object, por qué no podemos usar Dog reference and dog object?
pratyay
3
En el ejemplo anterior intenté mostrar el concepto de polimorfismo. podemos crear la referencia y el objeto de la misma clase pero no podemos lograr anular el método.
Continúe
la sobrecarga de métodos es el polimorfismo en tiempo de compilación. es de la misma manera. ¿La sobrecarga del constructor también es polimorfismo de tiempo de compilación?
Gaali Prabhakar
29
  • La sobrecarga de métodos sería un ejemplo de polimorfismo estático

  • mientras que anular sería un ejemplo de polimorfismo dinámico.

    Porque, en caso de sobrecarga, en el momento de la compilación el compilador sabe qué método enlazar con la llamada. Sin embargo, se determina en tiempo de ejecución para polimorfismo dinámico

usuario1374
fuente
17

El polimorfismo dinámico (tiempo de ejecución) es el polimorfismo existente en tiempo de ejecución. Aquí, el compilador de Java no comprende qué método se llama en el momento de la compilación. Solo JVM decide qué método se llama en tiempo de ejecución. La sobrecarga de métodos y la anulación de métodos utilizando métodos de instancia son los ejemplos de polimorfismo dinámico.

Por ejemplo,

  • Considere una aplicación que serializa y deserializa diferentes tipos de documentos.

  • Podemos tener 'Documento' como clase base y diferentes clases de tipo de documento que se deriven de él. Por ejemplo, XMLDocument, WordDocument, etc.

  • La clase de documento definirá los métodos 'Serialize ()' y 'De-serialize ()' como virtuales y cada clase derivada implementará estos métodos a su manera en función del contenido real de los documentos.

  • Cuando es necesario serializar / deserializar diferentes tipos de documentos, los objetos del documento serán referidos por la referencia de clase 'Documento' (o puntero) y cuando se llame al método 'Serialize ()' o 'De-serialize ()' en él, se llaman las versiones apropiadas de los métodos virtuales.

El polimorfismo estático (tiempo de compilación) es el polimorfismo exhibido en tiempo de compilación. Aquí, el compilador de Java sabe qué método se llama. Sobrecarga de métodos y anulación de métodos mediante métodos estáticos; La anulación de métodos mediante métodos privados o finales son ejemplos de polimorfismo estático.

Por ejemplo,

  • Un objeto de empleado puede tener dos métodos print (), uno sin argumentos y el otro con una cadena de prefijo que se mostrará junto con los datos del empleado.

  • Dadas estas interfaces, cuando se llama al método print () sin ningún argumento, el compilador, mirando los argumentos de la función, sabe qué función debe llamarse y genera el código objeto en consecuencia.

Para obtener más detalles, lea "Qué es el polimorfismo" (Google it).

rachana
fuente
2
Esta respuesta está llena de errores: (1) La sobrecarga de métodos no es un polimorfismo dinámico. Es polimorfismo estático. (2) Los métodos estáticos nunca se anulan, se ocultan / sombrean. (3) Los métodos privados no se "anulan". En primer lugar, nunca se heredan.
John Red
14

El enlace se refiere al vínculo entre la llamada al método y la definición del método.

Esta imagen muestra claramente lo que es vinculante.

Unión

En esta imagen, la llamada "a1.methodOne ()" se vincula a la definición correspondiente de methodOne () y la llamada "a1.methodTwo ()" se vincula a la definición correspondiente de methodTwo ().

Para cada llamada de método debe haber una definición de método adecuada. Esta es una regla en java. Si el compilador no ve la definición de método adecuada para cada llamada al método, arroja un error.

Ahora, pase al enlace estático y al enlace dinámico en java.

Enlace estático en Java:

El enlace estático es un enlace que ocurre durante la compilación. También se denomina enlace anticipado porque el enlace ocurre antes de que un programa se ejecute realmente.

.

La unión estática se puede demostrar como en la siguiente imagen.

ingrese la descripción de la imagen aquí

En esta imagen, 'a1' es una variable de referencia de tipo Clase A que apunta a un objeto de clase A. 'a2' también es una variable de referencia de tipo clase A pero que apunta a un objeto de Clase B.

Durante la compilación, mientras se vincula, el compilador no comprueba el tipo de objeto al que apunta una variable de referencia en particular. Simplemente verifica el tipo de variable de referencia a través del cual se llama a un método y verifica si existe una definición de método para él en ese tipo.

Por ejemplo, para la llamada al método “a1.method ()” en la imagen de arriba, el compilador verifica si existe una definición de método para el método () en la Clase A. Porque 'a1 ′ es de tipo Clase A. De manera similar, para la llamada al método “a2.method ()”, verifica si existe una definición de método para el método () en la Clase A. Porque 'a2 ′ también es de tipo Clase A. No comprueba a qué objeto apuntan 'a1' y 'a2'. Este tipo de enlace se denomina enlace estático.

Enlace dinámico en Java:

El enlace dinámico es un enlace que ocurre durante el tiempo de ejecución. También se denomina enlace tardío porque el enlace ocurre cuando el programa se está ejecutando.

Durante el tiempo de ejecución, los objetos reales se utilizan para la vinculación. Por ejemplo, para la llamada "a1.method ()" en la imagen de arriba, se llamará al método () del objeto real al que apunta "a1". Para la llamada "a2.method ()", se llamará al método () del objeto real al que apunta 'a2'. Este tipo de enlace se denomina enlace dinámico.

La unión dinámica del ejemplo anterior se puede demostrar como a continuación.

ingrese la descripción de la imagen aquí

Referencia de enlace-estático-y-enlace-dinámico-en-java

Elsayed
fuente
mejor que antes.
AnBisw
8

Polimorfismo: el polimorfismo es la capacidad de un objeto de adoptar muchas formas. El uso más común de polimorfismo en OOP ocurre cuando se usa una referencia de clase principal para hacer referencia a un objeto de clase secundaria.

Enlace dinámico / polimorfismo en tiempo de ejecución:

Polimorfismo en tiempo de ejecución también conocido como anulación de método. En este mecanismo mediante el cual se resuelve una llamada a una función anulada en un tiempo de ejecución.

public class DynamicBindingTest {

    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start();       //Car's start called because start() is overridden method
    }
}

class Vehicle {

    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {

    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}

Salida:

Método de arranque interior del coche

Enlace estático / polimorfismo en tiempo de compilación:

El método que se va a llamar se decide solo en tiempo de compilación.

public class StaticBindingTest {

    public static void main(String args[])  {
       Collection c = new HashSet();
       StaticBindingTest et = new StaticBindingTest();
       et.sort(c);

    }

    //overloaded method takes Collection argument
    public Collection sort(Collection c){
        System.out.println("Inside Collection sort method");
        return c;
    }


   //another overloaded method which takes HashSet argument which is sub class
    public Collection sort(HashSet hs){
        System.out.println("Inside HashSet sort method");
        return hs;
    }

}

Resultado: Método de ordenación de la colección interior

loknath
fuente
8

La sobrecarga de métodos es un ejemplo de tiempo de compilación / polimorfismo estático porque el enlace de método entre la llamada al método y la definición del método ocurre en el tiempo de compilación y depende de la referencia de la clase (la referencia se crea en el momento de la compilación y va a la pila).

La anulación de método es un ejemplo de polimorfismo dinámico / en tiempo de ejecución porque el enlace de método entre la llamada al método y la definición del método ocurre en el tiempo de ejecución y depende del objeto de la clase (objeto creado en tiempo de ejecución y va al montón).

Sujith PD
fuente
* (el objeto se crea en tiempo de ejecución y se va al montón), debería ejecutarse en tiempo
reunirse el
7

En lenguaje sencillo :

Polimorfismo estático : el mismo nombre de método está sobrecargado con diferente tipo o número de parámetros en la misma clase (firma diferente). La llamada al método de destino se resuelve en tiempo de compilación.

Polimorfismo dinámico : el mismo método se reemplaza con la misma firma en diferentes clases . El tipo de objeto en el que se invoca el método no se conoce en tiempo de compilación, pero se decidirá en tiempo de ejecución.

Generalmente, la sobrecarga no se considerará polimorfismo.

Desde la página del tutorial de Java :

Las subclases de una clase pueden definir sus propios comportamientos únicos y, sin embargo, compartir algunas de las mismas funciones de la clase principal.

Ravindra babu
fuente
Generally overloading won't be considered as polymorphism.¿Podría explicar este punto?
prime el
1
La vinculación dinámica y la anulación es un punto sorprendente para el polimorfismo
Ravindra babu
5

La sobrecarga de métodos se conoce como polimorfismo estático y también se conoce como polimorfismo en tiempo de compilación o enlace estático porque las llamadas a métodos sobrecargadas se resuelven en tiempo de compilación por el compilador sobre la base de la lista de argumentos y la referencia en la que estamos llamando al método.

Y el reemplazo de métodos se conoce como dinámica polimorfismo o simples polimorfismo o método en tiempo de ejecución de Despacho o enlace dinámico debido a la llamada método reemplazado se resuelve en tiempo de ejecución.

Con el fin de entender por qué esto es así Tomemos un ejemplo de Mammaly Humanclase

class Mammal {
    public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}

class Human extends Mammal {

    @Override
    public void speak() { System.out.println("Hello"); }

    public void speak(String language) {
        if (language.equals("Hindi")) System.out.println("Namaste");
        else System.out.println("Hello");
    }

}

He incluido la salida y el código de bytes de las siguientes líneas de código

Mammal anyMammal = new Mammal();
anyMammal.speak();  // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V

human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V

Y al mirar el código anterior, podemos ver que los códigos de bytes de humanMammal.speak (), human.speak () y human.speak ("Hindi") son totalmente diferentes porque el compilador es capaz de diferenciar entre ellos basándose en la lista de argumentos. y referencia de clase. Y es por eso que la sobrecarga de métodos se conoce como polimorfismo estático .

Pero el código de bytes para anyMammal.speak () y humanMammal.speak () es el mismo porque, según el compilador, ambos métodos se invocan en la referencia Mammal, pero la salida para ambas llamadas a métodos es diferente porque en tiempo de ejecución, JVM sabe qué objeto contiene una referencia y las llamadas JVM. el método en el objeto y esta es la razón por la que la anulación de método se conoce como polimorfismo dinámico.

Entonces, del código anterior y del código de bytes, está claro que durante la fase de compilación, el método de llamada se considera desde el tipo de referencia. Pero en el momento de la ejecución se llamará al método desde el objeto que contiene la referencia.

Si desea saber más sobre esto, puede leer más sobre cómo JVM maneja la sobrecarga y la anulación de métodos internamente .

Naresh Joshi
fuente
3

Polimorfismo estático: es donde la decisión de resolver qué método realizar, se determina durante el tiempo de compilación. La sobrecarga de métodos podría ser un ejemplo de esto.

Polimorfismo dinámico: es donde la decisión de elegir qué método ejecutar, se establece durante el tiempo de ejecución. La anulación de método podría ser un ejemplo de esto.

Kulasangar
fuente
3

El polimorfismo se refiere a la capacidad de un objeto de comportarse de manera diferente para el mismo disparador.

Polimorfismo estático (polimorfismo en tiempo de compilación)

  • El polimorfismo estático decide qué método ejecutar durante el tiempo de compilación.
  • La sobrecarga de métodos es un ejemplo de polimorfismo estático, y se requiere que ocurra un polimorfismo estático.
  • Polimorfismo estático logrado mediante enlace estático.
  • El polimorfismo estático ocurre en la misma clase.
  • La asignación de objetos no es necesaria para el polimorfismo estático.
  • La herencia no está involucrada en el polimorfismo estático.

Polimorfismo dinámico (polimorfismo en tiempo de ejecución)

  • El polimorfismo dinámico decide qué método ejecutar en tiempo de ejecución.
  • El método Overriding es un ejemplo de polimorfismo dinámico, y se requiere que ocurra un polimorfismo dinámico.
  • Polimorfismo dinámico logrado mediante enlace dinámico.
  • El polimorfismo dinámico ocurre entre diferentes clases.
  • Es necesario cuando se asigna un objeto de subclase a un objeto de superclase para el polimorfismo dinámico.
  • Herencia involucrada para el polimorfismo dinámico.
Saveendra Ekanayake
fuente
1

Polimorfismo en tiempo de compilación (enlace estático / enlace temprano): en el polimorfismo estático, si llamamos a un método en nuestro código, la definición de ese método que se va a llamar se resuelve solo en tiempo de compilación.

(o)

En el momento de la compilación, Java sabe qué método invocar comprobando las firmas del método. Entonces, esto se llama polimorfismo en tiempo de compilación o enlace estático.

Polimorfismo dinámico (enlace tardío / polimorfismo en tiempo de ejecución): en tiempo de ejecución, Java espera hasta el tiempo de ejecución para determinar a qué objeto está apuntando realmente la referencia. La resolución del método se tomó en tiempo de ejecución, por lo que llamamos polimorfismo en tiempo de ejecución.

Pavan Reddy
fuente
1

Considere el siguiente código:

public class X
{
    public void methodA() // Base class method
    {
        System.out.println ("hello, I'm methodA of class X");
    }
}

public class Y extends X
{
    public void methodA() // Derived Class method
    {
        System.out.println ("hello, I'm methodA of class Y");
    }
}
public class Z
{
public static void main (String args []) {

    //this takes input from the user during runtime
    System.out.println("Enter x or y");
    Scanner scanner = new Scanner(System.in);
    String value= scanner.nextLine();

    X obj1 = null;
    if(value.equals("x"))
        obj1 = new X(); // Reference and object X
    else if(value.equals("y"))
        obj2 = new Y(); // X reference but Y object
    else
        System.out.println("Invalid param value");

    obj1.methodA();
}
}

Ahora, mirando el código, nunca se puede saber qué implementación del método A () se ejecutará, porque depende del valor que el usuario dé durante el tiempo de ejecución. Por lo tanto, solo se decide durante el tiempo de ejecución qué método se llamará. Por lo tanto, polimorfismo en tiempo de ejecución.

user2048204
fuente
0

La sobrecarga de métodos es un polimorfismo en tiempo de compilación, tomemos un ejemplo para entender el concepto.

class Person                                            //person.java file
{
    public static void main ( String[] args )
    {
      Eat e = new Eat();
       e.eat(noodle);                                //line 6
    }

   void eat (Noodles n)      //Noodles is a object    line 8                     
   {

   }
   void eat ( Pizza p)           //Pizza is a object
  {

  }

}

En este ejemplo, Person tiene un método de comer que representa que puede comer pizza o fideos. Que el método eat está sobrecargado cuando compilamos este Person.java, el compilador resuelve la llamada al método "e.eat (noodles) [que está en la línea 6] con la definición del método especificada en la línea 8, que es el método que toma fideos como parámetro y todo el proceso lo realiza el Compilador, por lo que es Polimorfismo en tiempo de compilación El proceso de reemplazo de la llamada al método con la definición del método se llama como enlace, en este caso, lo realiza el compilador por lo que se llama como enlace temprano.

Manoj Gururaj
fuente
0

Siguiendo la respuesta de Naresh, el polimorfismo dinámico es solo 'dinámico' en Java debido a la presencia de la máquina virtual y su capacidad para interpretar el código en tiempo de ejecución en lugar del código que se ejecuta de forma nativa.

En C ++ debe resolverse en tiempo de compilación si se está compilando en un binario nativo usando gcc, obviamente; sin embargo, el salto y el procesador en tiempo de ejecución en la tabla virtual todavía se conoce como "búsqueda" o "dinámica". Si C hereda B, y usted declara B* b = new C(); b->method1();, b será resuelto por el compilador para apuntar a un objeto B dentro de C (para una clase simple hereda una situación de clase, el objeto B dentro de C y C comenzará en la misma dirección de memoria así que nada es necesario hacerlo; apuntará al vptr que ambos usan). Si C hereda B y A, la tabla de función virtual del objeto A dentro de la entrada C para el método1 tendrá un procesador que desplazará el puntero al inicio del objeto C encapsulado y luego lo pasará al A :: método1 () real en el segmento de texto que C ha anulado. porC* c = new C(); c->method1(), c ya apuntará al objeto C externo y el puntero se pasará a C :: method1 () en el segmento de texto. Consulte: http://www.programmersought.com/article/2572545946/

En java, para B b = new C(); b.method1();, la máquina virtual es capaz de verificar dinámicamente el tipo de objeto emparejado con by puede pasar el puntero correcto y llamar al método correcto. El paso adicional de la máquina virtual elimina la necesidad de tablas de funciones virtuales o el tipo que se resuelve en el momento de la compilación, incluso cuando podría conocerse en el momento de la compilación. Es solo una forma diferente de hacerlo, lo que tiene sentido cuando se trata de una máquina virtual y el código solo se compila en bytecode.

Lewis Kelsey
fuente