que identifique generar documentacion comentarios codigo averigue all java oop method-hiding

identifique - ¿Qué es el método oculto en Java? Incluso la explicación de JavaDoc es confusa



javadoc pdf (5)

Javadoc dice:

la versión del método oculto que se invoca es la de la superclase, y la versión del método reemplazado que se invoca es la de la subclase.

no me suena una campana. Cualquier ejemplo claro que demuestre el significado de esto será muy apreciado.


En primer lugar, ¿qué se entiende por método de ocultación?

Método de ocultamiento significa que la subclase ha definido un método de clase con la misma firma que un método de clase en la superclase. En ese caso, el método de la superclase está oculto por la subclase. Significa que: La versión de un método que se ejecuta NO será determinada por el objeto que se utiliza para invocarlo . De hecho, estará determinado por el tipo de variable de referencia utilizada para invocar el método .

¿Qué se entiende por anulación de método?

La anulación de método significa que la subclase ha definido un método de instancia con la misma firma y el mismo tipo de retorno (incluido el tipo covariante) que el método de instancia en la superclase. En ese caso, la subclase anula (reemplaza) el método de superclase. Significa que: La versión del método que se ejecuta estará determinada por el objeto que se utiliza para invocarlo . No estará determinado por el tipo de variable de referencia utilizada para invocar el método .

¿Por qué no se pueden anular los métodos estáticos?

Porque los métodos estáticos se resuelven estáticamente (es decir, en tiempo de compilación) en función de la clase a la que se invocan y no dinámicamente como en el caso de los métodos de instancia que se resuelven polimórficamente en función del tipo de tiempo de ejecución del objeto.

¿Cómo deben accederse los métodos estáticos?

Se debe acceder a los métodos estáticos de forma estática. es decir, por el nombre de la clase en sí misma en lugar de usar una instancia.

Aquí está la demostración corta para el método de anulación y ocultación:

class Super { public static void foo(){System.out.println("I am foo in Super");} public void bar(){System.out.println("I am bar in Super");} } class Child extends Super { public static void foo(){System.out.println("I am foo in Child");}//Hiding public void bar(){System.out.println("I am bar in Child");}//Overriding public static void main(String[] args) { Super sup = new Child();//Child object is reference by the variable of type Super Child child = new Child();//Child object is referenced by the variable of type Child sup.foo();//It will call the method of Super. child.foo();//It will call the method of Child. sup.bar();//It will call the method of Child. child.bar();//It will call the method of Child again. } }

La salida es

I am foo in Super I am foo in Child I am bar in Child I am bar in Child

Claramente, como se especifica, dado que foo es el método de clase, entonces la versión de foo invocada estará determinada por el tipo de variable de referencia (es decir, Super o Child) que hace referencia al objeto de Child . Si se hace referencia a foo se llama a foo de Super . Y si se hace referencia a Child variable Child entonces se llama a foo of Child .
Considerando que ,
Dado que bar es el método de instancia, la versión de la bar invocada está determinada únicamente por el objeto (es decir, Child ) que se utiliza para invocarlo. No importa a través de qué variable de referencia ( Super o Child ) se llame, el método que se va a llamar es siempre de Child .


Por ejemplo, puede anular los métodos de instancia en una superclase pero no estática.

Ocultar es clase primaria tiene un método estático llamado Foo y la clase secundaria también tiene un método estático llamado Foo.

Otro escenario es que el padre tiene un método estático llamado Cat y la subclase tiene un método de instancia llamado Cat. (estática e instancia con la misma firma no se pueden mezclar).

public class Animal { public static String getCat() { return "Cat"; } public boolean isAnimal() { return true; } } public class Dog extends Animal { // Method hiding public static String getCat() { } // Not method hiding @Override public boolean isAnimal() { return false; } }


Si una subclase define un método de clase con la misma firma que un método de clase en la superclase, el método en la subclase oculta el de la superclase.

Los métodos ocultos están en contexto estático, creo. Los métodos estáticos no se anulan, per se, porque la resolución de las llamadas a métodos las realiza el compilador en el momento de la compilación. Entonces, si defines un método estático en la clase base con la misma firma que el presente en la clase padre, entonces el método en la subclase oculta el método heredado de la superclase.

class Foo { public static void method() { System.out.println("in Foo"); } } class Bar extends Foo { public static void method() { System.out.println("in Bar"); } }


Sobrescribir un método significa que siempre que se llame al método sobre un objeto de la clase derivada, se llamará a la nueva implementación.

Ocultar un método significa que una llamada no calificada a ese nombre en el ámbito de esta clase (es decir, en el cuerpo de cualquiera de sus métodos, o cuando esté calificado con el nombre de esta clase) ahora llamará a una función completamente diferente, que requiere una calificación para acceder al método estático del mismo nombre de la clase padre .

Más descripción Herencia de Java: métodos sobrescritos u ocultos


public class Animal { public static void foo() { System.out.println("Animal"); } } public class Cat extends Animal { public static void foo() { // hides Animal.foo() System.out.println("Cat"); } }

Aquí, se dice que Animal.foo() oculta Animal.foo() . Ocultar no funciona como anulación, porque los métodos estáticos no son polimórficos. Entonces, sucederá lo siguiente:

Animal.foo(); // prints Animal Cat.foo(); // prints Cat Animal a = new Animal(); Animal b = new Cat(); Cat c = new Cat(); Animal d = null; a.foo(); // should not be done. Prints Animal because the declared type of a is Animal b.foo(); // should not be done. Prints Animal because the declared type of b is Animal c.foo(); // should not be done. Prints Cat because the declared type of c is Cat d.foo(); // should not be done. Prints Animal because the declared type of d is Animal

Llamar a métodos estáticos en instancias en lugar de clases es una práctica muy mala, y nunca debería hacerse.

Compare esto con los métodos de instancia, que son polimórficos y se anulan. El método llamado depende del tipo de tiempo de ejecución concreto del objeto:

public class Animal { public void foo() { System.out.println("Animal"); } } public class Cat extends Animal { public void foo() { // overrides Animal.foo() System.out.println("Cat"); } }

Entonces sucederá lo siguiente:

Animal a = new Animal(); Animal b = new Cat(); Animal c = new Cat(); Animal d = null; a.foo(); // prints Animal b.foo(); // prints Cat c.foo(); // prints Cat d.foo(): // throws NullPointerException