Programación 3

Universidad de Alicante, 2018–2019

Ejercicios sobre enlace dinámico y sobrescritura

(Pulsa aquí para la versión para imprimir

Ejemplo visto en clase (UD 5)

En la figura puedes ver un ejemplo de la organización en memoria de los objetos y clases de un programa en ejecución. Las variables locales y argumentos de un método se almacenan en la pila (stack), mientras que los objetos se almacenan en el heap o, como se conoce en la jerga de C++, la memoria dinámica. En el área de métodos (method area) se almacenan las implementaciones de los métodos (sus instrucciones).

Cuando creamos un objeto (con new), este se crea en el heap y su dirección se guarda en una referencia en el stack (la variable a del ejemplo).

Date cuenta como, en tiempo de ejecución, la máquina virtual dispone de la información necesaria para enlazar las llamadas a.walk() y a.die() en tiempo de ejecución.

Ejemplo de la organización en memoria de un proceso en la máquina virtual de Java
Ejemplo de la organización en memoria de un proceso en la máquina virtual de Java

Prueba lo siguiente:

  • Reproduce mentalmente los pasos que sigue la máquina virtual para encontrar el código del método que tiene que enlazar a las llamadas a.walk() y a.die()
  • Indica qué ocurre si escribimos la instrucción a.meow()
  • Indica cómo harías ladrar al perro.
  • Añade un segundo perro al código y modifica el diagrama para reflejar esa situación.
  • ¿Qué ocurre si invocamos a Animal.getCount()?
  • Añade un gato al código, guardando la dirección del nuevo objeto en una referencia de tipo Animal. Modifica el diagrama para reflejar la situación. Ejecuta el método walk() sobre él y reproduce los pasos del enlace dinámico como hiciste antes. ¡Deberías llegar al código de Cat.walk()!

Copia profunda y copia superficial

El siguiente código define las clases Circulo y Coord.

Haz lo siguiente:

  • Implementa el constructor de copia de Circulo como copia superficial y dibuja un diagrama similar al del ejercicio anterior que refleje la situación en memoria en tiempo de ejecución tras ejecutar el código cliente.

  • Implementa el constructor de copia de Circulo como copia profunda y refleja en el diagrama los cambios que se producirían.

Covarianza (sobrescritura, UD6)

El siguiente código crea dos jerarquías de herencia: la superclase A y su subclase B, y la superclase Super y su subclase Sub. Estas dos últimas contienen un subobjeto de clase A y B, respectivamente. Fíjate como el método getA() devuelve un B en la clase Sub. A este cambio en el tipo devuelto por un método sobrescrito se le llama covarianza y a los tipos relacionados (A y B), tipos covariantes. Siempre deben ser tipos relacionados mediante herencia.

Haz lo siguiente:

  • Dibuja, como antes, el diagrama de la disposición en memoria de los objetos y sus objetos Class tras la ejecución del código cliente hasta el comentario 1.

  • Explica qué ocurre con las dos llamadas a getA(), basándote en el diagrama.