Anulando los métodos en java y luego convirtiendo el objeto en el comportamiento de clase principal

Tengo una clase principal, A y una clase secundaria, B y B anulan un método, f, de A.

public class A { public String f() { return "A"; } } public class B extends A { ... public String f() { return "B"; } public static void main(String[] args) { B b = new B(); A a = (A) b; System.out.println(bf()); //prints: B } } 

Creo un objeto de tipo B, b, y lo echo a escribir A y lo asigno a una variable de tipo A, a, y luego llamo al método f en a. Ahora esperaría que se llamara el método de la clase padre, ya que estoy trabajando con un objeto de Tipo A pero no, llama a la versión b del método (imprime “B” en lugar de “A” en el código a continuación).

¿Por qué es como este? ¿Es una decisión de diseño o un límite de tecnología?

Esta es la base del polymorphism.

Y se supone que funciona así.

Cualquier método se envía (selecciona / invoca) dinámicamente de acuerdo con el tipo real del objeto en lugar del tipo al que se lo está haciendo referencia.

Cuando lanzas el objeto a otro tipo, simplemente lo refieres usando otro tipo. El tipo real del objeto no se cambia. (Y nunca puede cambiar).

Así que el comportamiento que está observando es el esperado y está diseñado para ser así. Definitivamente no es una limitación.

Espero que esto ayude.

Es una decisión de diseño. Has creado un objeto de tipo “B”, así que eso es lo que es.

Cuando lo transfiere a A, solo le está diciendo al intérprete que los métodos que se esperan encontrar en una clase de tipo A están disponibles para B, pero dado que tiene un método @Override para B, lo usará.

A a = (A) b;

Al convertir la variable a la referencia no ha cambiado, por lo que el método f aún se invoca, ya que las llamadas a métodos son polimórficas.

Cuando lanzas la instancia simplemente estás implicando que podría ser una instancia de la superclase, PERO la implementación interna de esa instancia no cambiará, ¡por eso obtienes ese resultado!

Metafóricamente hablando, si aplicaras la máscara de persona de un estadounidense a una persona del Reino Unido (elenco), esa persona seguiría siendo inglesa (herencia), pero si le pides a esa persona que hable (llamando a un método) aún escucharás el acento británico, no el americano (la implementación interna es lo que importa al final) 🙂

Así es como se supone que debe funcionar. Está llamando al método en B porque así se creó la instancia de la variable. El tipo de la variable a la que fue asignado no cambia el hecho de que a es en realidad de tipo B La mayoría de los lenguajes son así, incluido C #.