simple multiple herencia ejercicios ejemplos con animales java inheritance methods constructor override

multiple - Salida perpleja en Java con métodos de herencia y anulación



herencia multiple en java ejemplos (1)

Hay algunos hechos que debe saber antes de comenzar a explicar cada paso de la ejecución del código:

  • Las referencias de campo se resuelven según el tipo de referencia y las llamadas al método se resuelven durante el tiempo de ejecución (de forma dinámica) en función del tipo de objeto.
  • super() se coloca implícitamente en cada constructor, incluso si no lo pones allí mismo (no se llama si llamas a super(int x, int y) por ejemplo).
  • Se considera una muy mala práctica llamar a los métodos "anulables" de un constructor; verás por qué cuando pasamos por la ejecución.

Ahora desglosemos su código paso a paso:

  • Crea una instancia de B llamando a su constructor predeterminado B() .
  • Como dije antes, la llamada a super() se agrega implícitamente a cualquier constructor, por lo que A() se llama inmediatamente.
  • Dentro de A() llama a foo() , que está anulado en la clase B y es por eso que se llama a foo() desde B
  • Dentro de foo() B obtienes la salida B.foo(): bar = null ya que Java no llegó a inicializar los campos de B (¡su constructor no se ha ejecutado todavía!) Y los campos de tipo de objeto se inicializan a null por defecto.
  • Ahora que hemos terminado con el constructor de A() volvemos al constructor de B() .
  • Dentro de dicho constructor, tenemos la llamada a foo() otra vez, que es otra vez B ''s foo() . Pero a diferencia de la última vez, B tiene sus campos inicializados (después de la llamada a super() ) correctamente, por lo que obtienes el esperado B.foo(): bar = B.bar .
  • Ahora hemos vuelto al cálido abrazo de main .
  • Usted accede a a.bar , y como dije que las referencias de campo se resuelven según el tipo de referencia, obtiene la bar de campo de A
  • Por último, por la misma razón, se llama a.foo() que de nuevo desencadena el foo() B que imprime b.bar una vez más.

Y hemos terminado! :)

Referencias adicionales y materiales de lectura que valen la pena:
Explicación estática y dinámica explicada
Orden de llamadas de constructor

Me encontré con esta pieza de código.
Traté de adivinar cuál será el resultado de ejecutarlo antes de hacerlo realmente. Estaba realmente confundido cuando los vi y necesitaba algunas explicaciones.
Este es el código:

public class A { String bar = "A.bar"; A() { foo(); } public void foo() { System.out.println("A.foo(): bar = " + bar); } } public class B extends A { String bar = "B.bar"; B() { foo(); } public void foo() { System.out.println("B.foo(): bar = " + bar); } } public class C { public static void main(String[] args) { A a = new B(); System.out.println("a.bar = " + a.bar); a.foo(); } }

El resultado es:

B.foo(): bar = null B.foo(): bar = B.bar a.bar = A.bar B.foo(): bar = B.bar

¿Porqué es eso?

  • ¿Cómo es bar = null ?
  • ¿Por qué aparece a.bar = A.bar incluso? No he instanciado A en absoluto.
  • Y si aparece A , ¿por qué es después de B ?