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


Javadoc dice:

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

No me suena. Cualquier ejemplo claro que muestre el significado de esto será muy apreciado.

Author: Senthil Kumaran, 2013-05-01

5 answers

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í, Cat.foo() se dice que ocultar Animal.foo(). Ocultar no funciona como sobreescribir, porque los métodos estáticos no son polimórficos. Así que 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 muy mala práctica, y nunca debe hacerse.

Compare esto con los métodos de instancia, que son polimórficos y, por lo tanto, se anulan. El método llamado depende del tipo concreto de tiempo de ejecución 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 lo siguiente será suceder:

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
 112
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 13:13:05

En primer lugar, ¿qué se entiende por método oculto?

Método ocultar 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 estará determinada por el objeto que se utiliza para invocarlo. De hecho, se determinará por el tipo de referencia variable utilizada para invocar el método .

¿Qué se entiende por sobreescritura de método?

La sobreescritura del método significa que la subclase ha definido un método de instancia con la misma firma y tipo de retorno( incluido el tipo covariante) que el método de instancia en superclase. En ese caso, el método de la superclase se sobrescribe (reemplaza) por la subclase. Significa que: La versión del método que se ejecuta será determinada por el objeto eso se usa para invocarlo . No se determinará 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 son llamados 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 ¿se debe acceder a los métodos estáticos?

Los métodos estáticos deben ser accedidos de manera estática. es decir, por el nombre de la propia clase en lugar de usar una instancia.

Aquí está la breve demostración para el método sobreescribir y ocultar:

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, 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 por Super variable entonces foo de Super se llama. Y si es referenciada por Child variable entonces se llama foo de Child.
Considerando que ,
Dado que bar es el método de instancia, la versión de 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 llama , el método que se va a llamar es siempre de Child.

 32
Author: Vishal K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-13 20:57:06

A sobrescribir un método significa que cada vez que se invoca al método en un objeto de la clase derivada, se llamará a la nueva implementación.

To hide 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 se califica con el nombre de esta clase) ahora llamará a una función completamente diferente, requiriendo una calificación para acceder al método estático del mismo clase.

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

 3
Author: ꜱᴜʀᴇꜱʜ ᴀᴛᴛᴀ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:31

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 de 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, debido a la resolución de las llamadas a los métodos realizadas por el compilador en el propio tiempo de compilación. Por lo tanto, si define un método estático en la clase base con la misma firma que la 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");
  }
}
 2
Author: NINCOMPOOP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-01 06:32:23

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

Hiding is Parent class tiene un método estático llamado Foo y la subclase 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 pueden mezclarse).

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; }
}
 1
Author: Jeremy Unruh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-01 06:28:20