2012-03-28 19 views
5

¿Tanto la herencia como el polimorfismo constituyen una relación IS-A? ¿Y es cierto que la herencia y el polimorfismo "predominante" suceden en tiempo de ejecución mientras que el polimorfismo "sobrecargado" ocurre en tiempo de compilación? La razón por la que pregunto esto es porque muchos foros parecen dar respuestas conflictivas ya menudo confusas.Herencia de Java vs polimorfismo

Gracias!

+3

Creo que la sobrecarga no tiene nada que ver con el polimorfismo. – ka3ak

+0

En realidad, esta es una forma de polimorfismo: de Wikipedia: el término polimorfismo ad-hoc para referirse a funciones polimórficas que se pueden aplicar a argumentos de diferentes tipos, pero que se comportan de manera diferente según el tipo de argumento al que se aplican (también conocido como sobrecarga de funciones o sobrecarga del operador) .. –

+0

@edalorzo: se disputa la exactitud de los hechos de http://en.wikipedia.org/wiki/Ad-hoc_polymorphism. – Jayan

Respuesta

8

en tiempo de compilación Para su primera parte de la pregunta creo Wikipedia proporciona una buena definición:

En la programación orientada a objetos, el polimorfismo subtipo o inclusión polimorfismo es un concepto en la teoría de tipos en el que un nombre puede denotar instancias de de muchas clases diferentes, siempre que estén relacionadas por alguna clase común de . El polimorfismo de inclusión generalmente es soportado a través de la subtipificación, es decir, los objetos de diferentes tipos son completamente sustituibles por objetos de otro tipo (sus tipos base tipo (s)) y por lo tanto pueden manejarse a través de una interfaz común. Alternativamente, el polimorfismo de inclusión se puede lograr a través del tipo coerción, también conocido como tipo de fundición.

Otra Wikipedia llamada Polymorphism in object-oriented programming parece responder a sus preguntas muy bien. La segunda referencia en este artículo llamada On Understanding Types, Data Abstraction, and Polymorphism también cubre este asunto con gran detalle.

Esta función de subtipado en Java se logra, entre otros medios, a través de la herencia de clases e interfaces. Aunque las características de subtipado de Java pueden no ser evidentes en términos de herencia todo el tiempo. Tomemos, por ejemplo, los casos de covarianza y contravarianza con genéricos. Además, las matrices son serializables y clonables, aunque esto no es evidente en ninguna parte de la jerarquía de tipos. También se puede decir que a través de la conversión de ampliación primitiva, también los tipos numéricos en Java son polimórficos. Y el operador se comporta polimórficamente dependiendo de sus operandos.

En cualquier caso, la herencia juega un papel importante en la implementación de parte de este polimorfismo.

sobrecarga vs Anulación

Su segunda parte de la pregunta parece ser sobre la elección de la implementación de un método dado. Evidentemente, si una clase anula un método y usted crea una instancia de esa clase, quiere que se invoque la versión anulada del método, incluso si está accediendo al objeto a través de una referencia de la clase padre.

La selección de la implementación correcta del método se realiza en tiempo de ejecución como bien indicó, ahora la firma del método que se va a invocar se decide en tiempo de compilación. Como la sobrecarga se trata de diferentes métodos con el mismo nombre y una firma diferente, es por eso que se dice que la selección del método de anulación ocurre en el momento de la compilación.

Anulación Método de selección en tiempo de compilación

El Java Language Specification (JLS) en la sección 15.12 Method Invocation Expressions explica en detalle el proceso que sigue el compilador para elegir el método adecuado para invocar.

Allí observará que se trata de una tarea en tiempo de compilación. El JLS dice en el párrafo 15.12.2:

Este paso utiliza el nombre del método y los tipos de argumento expresiones de para localizar métodos que son a la vez accesible y aplicable Puede haber más de uno de esos métodos, en cuyo caso se elige el más específico.

Para verificar la naturaleza del tiempo de compilación de esto, puede hacer la siguiente prueba.

Declara una clase como esta y compilala.

public class ChooseMethod { 
    public void doSomething(Number n){ 
    System.out.println("Number"); 
    } 
} 

Declara una segunda clase que invoca un método del primero y lo compila.

public class MethodChooser { 
    public static void main(String[] args) { 
    ChooseMethod m = new ChooseMethod(); 
    m.doSomething(10); 
    } 
} 

Si se invoca el principal, la salida dice Number.

Ahora, agregue un segundo más específica sobrecargado método a la clase ChooseMethod y compilarlo (pero no vuelva a compilar la otra clase).

public void doSomething(Integer i) { 
System.out.println("Integer"); 
} 

Si ejecuta el principal nuevo, la salida sigue siendo Number.

Básicamente, porque se decidió en tiempo de compilación. Si vuelve a compilar la clase MethodChooser (la que tiene la principal) y vuelve a ejecutar el programa, la salida será Integer.

Como tal, si desea forzar la selección de uno de los métodos sobrecargados, el tipo de argumentos debe corresponderse con el tipo de parámetros en tiempo de compilación, y no solo en tiempo de ejecución.

Anulación Método de selección en tiempo de ejecución

Una vez más, la firma del método se decide en tiempo de compilación, pero la implementación real se decide en tiempo de ejecución.

Declara una clase como esta y compilala.

public class ChooseMethodA { 
    public void doSomething(Number n){ 
    System.out.println("Number A"); 
    } 
} 

Entonces declarar una segunda clase que se extiende y compilar:

public class ChooseMethodB extends ChooseMethodA { } 

Y en la clase MethodChooser haces:

public class MethodChooser { 
    public static void main(String[] args) { 
     ChooseMethodA m = new ChooseMethodB(); 
     m.doSomething(10); 
    } 
} 

Y si lo ejecuta se obtiene la salida Number A, y esto está bien, porque el método no ha sido anulado en ChooseMethodB y, por lo tanto, la implementación que se invoca es la de ChooseMethodA.

Ahora, agregue un método sobreescrito en MethodChooserB:

public void doSomething(Number n){ 
    System.out.println("Number B"); 
} 

y recompilar solo este, y ejecute el método principal de nuevo.

Ahora, se obtiene la salida Number B

Como tal, la ejecución fue elegido en tiempo de ejecución, y se requiere no recompilación de la clase MethodChooser.

+2

La respuesta de Jayan es bastante sucinta, creo. – shiva

0

El polimorfismo es un efecto de la herencia. Solo puede suceder en clases que se extienden entre sí.

El polimorfismo ocurre en tiempo de ejecución; Nunca he oído hablar de "polimorfismo sobrecargado".

Herencia sucede en tiempo de compilación, el momento en que escribir:

class A extends B 
{ 
} 
0

única herencia constituye una relación es-un. polimorfismo no tiene nada que ver con eso.

"sobrecarga" es un ejemplo de polimorfismo. Se puede obtener más información sobre el tiempo de ejecución y el polimorfismo here

1

Creo que tienes razón.

El polimorfismo considera el tipo de tiempo de ejecución del objeto para decidir qué método ejecutar y la elección del método sobrecargado para llamar no se decide dinámicamente en tiempo de ejecución, depende de los tipos de parámetros en tiempo de compilación.

5

Polimorfismo: capacidad de diferentes objetos para recibir el mismo mensaje y responder de manera diferente.

Su herencia es una forma de lograrlo, pero no es necesario. Ver Duck Typing

La sobrecarga de un método es 'tiempo de compilación sintaxis auxiliar', ya que cada método obtiene una firma única después de la compilación. Realmente no tiene nada que ver con el polimorfismo.

0

• La herencia define la relación padre-hijo entre dos clases, el polimorfismo aprovecha esa relación para agregar un comportamiento dinámico en el código.

• La herencia fomenta la reutilización del código al permitir que la clase hija herede el comportamiento de la clase principal. Por otro lado, el polimorfismo le permite al niño redefinir el comportamiento ya definido dentro de la clase principal. Sin polimorfismo, no es posible que un niño ejecute su propio comportamiento mientras está representado por una variable de referencia principal, pero con polimorfismo se puede hacer.

• Java no permite la herencia múltiple de las clases, pero permite la herencia múltiple de la interfaz, que en realidad se requiere para implementar el polimorfismo. Por ejemplo, una clase puede ser Runnable, Comparator y Serializable al mismo tiempo porque las tres son interfaces. Esto los hace pasar en código, p. puede pasar una instancia de esta clase a un método que acepte Serializable, o a Collections.sort() que acepte un Comparador.

• Tanto el polimorfismo como la herencia permiten que los programas orientados a objetos evolucionen. Por ejemplo, al usar herencia, puede definir nuevos tipos de usuario en un sistema de autenticación y, mediante el uso de polimorfismo, puede aprovechar el código de autenticación ya escrito. Dado que, la herencia garantiza el comportamiento de la clase base mínima, un método que depende de la superclase o superinterfaz puede aceptar un objeto de la clase base y puede autenticarlo.