¿Alguien puede proporcionar un ejemplo simple que explique la diferencia entre el polimorfismo dinámico y estático en Java?
java
oop
polymorphism
overloading
overriding
Prabhakar Manthena
fuente
fuente
Respuestas:
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:
ejemplo primordial:
fuente
Animal reference but Dog object
, por qué no podemos usarDog reference and dog object
?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
fuente
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).
fuente
Esta imagen muestra claramente lo que es vinculante.
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:
.
La unión estática se puede demostrar como en la siguiente imagen.
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:
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.
Referencia de enlace-estático-y-enlace-dinámico-en-java
fuente
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.
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.
Resultado: Método de ordenación de la colección interior
fuente
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).
fuente
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 :
fuente
Generally overloading won't be considered as polymorphism.
¿Podría explicar este punto?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
Mammal
yHuman
claseHe incluido la salida y el código de bytes de las siguientes líneas de código
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 .
fuente
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.
fuente
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)
Polimorfismo dinámico (polimorfismo en tiempo de ejecución)
fuente
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.
fuente
Considere el siguiente código:
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.
fuente
La sobrecarga de métodos es un polimorfismo en tiempo de compilación, tomemos un ejemplo para entender el concepto.
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.
fuente
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.fuente