java - ¿Por qué no se queja el compilador cuando intento anular un método estático?
static-methods method-overriding (8)
Sé que no podemos anular los métodos estáticos en Java, pero ¿alguien puede explicar el siguiente código?
class A {
public static void a() {
System.out.println("A.a()");
}
}
class B extends A {
public static void a() {
System.out.println("B.a()");
}
}
¿Cómo pude anular el método a()
en la clase B
?
Además, la elección del método para llamar depende del tipo declarado de la variable.
B b = null;
b.a(); // (1) prints B.a()
A a = new B();
a.a(); // (2) prints a.a()
En (1), si el sistema se preocupa por la identidad de b
, arrojaría un NPE
. y en (2), el valor de a
se ignora. Como a
se declara como A
, se llama Aa()
.
Eso se llama hiding a method
, como se indica en el tutorial de Java Métodos de anulación y ocultación :
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 estáticos serán llamados por su nombre de clase, por lo que no es necesario crear un objeto de clase, simplemente lo llamamos con el nombre de clase, por lo que no podemos anular la estática.
por ejemplo
class AClass{
public static void test(){
}
}
class BClass extends AClass{
public static void test(){}
}
class CClass extends BClass{
public static void main(String args[]){
AClass aclass=new AClass();
aclass.test(); // its wrong because static method is called
// by its class name it can''t accept object
}
}
solo lo llamamos
AClass.test();
significa que la clase estática no puede anularse si se reemplaza, sino cómo calcarla.
No anuló el método a()
, porque static
métodos static
no se heredan. Si hubiera puesto @Override
, habría visto un error.
A.java:10: error: method does not override or implement a method from a supertype
@Override
^
1 error
Pero eso no le impide definir métodos estáticos con la misma firma en ambas clases.
No anuló nada aquí. Para comprobarlo usted mismo, intente poner la anotación @Override
antes de public static void a()
en la clase B
y Java arrojará un error.
Usted acaba de definir una función en la clase B
llamada a()
, que es distinta (sin relación alguna) de la función a()
en la clase A
Pero debido a que Ba()
tiene el mismo nombre que una función en la clase principal, oculta Aa()
[Según lo indicado por Eng. Fouad]. En tiempo de ejecución, el compilador usa la clase real de la referencia declarada para determinar qué método ejecutar. Por ejemplo,
B b = new B();
b.a() //prints B.a()
A a = (A)b;
a.a() //print A.a(). Uses the declared reference''s class to find the method.
No puede anular los métodos estáticos en Java. Recuerde que static
métodos y campos static
están asociados con la clase, no con los objetos. (Aunque, en algunos idiomas como Smalltalk, esto es posible).
Encontré algunas buenas respuestas aquí: ¿Por qué Java no permite la anulación de métodos estáticos?
Si bien se aceptó la respuesta goblinjuice, pensé que el código de ejemplo podría mejorar:
public class StaticTest {
public static void main(String[] args) {
A.print();
B.print();
System.out.println("-");
A a = new A();
B b = new B();
a.print();
b.print();
System.out.println("-");
A c = b;
c.print();
}
}
class A {
public static void print() {
System.out.println("A");
}
}
class B extends A {
public static void print() {
System.out.println("B");
}
}
Produce:
A
B
-
A
B
-
A
Si B hubiera reemplazado a print()
, escribiría B en la línea final.
Su método no es un método anulado. simplemente intenta poner la anotación @Override antes de su método en la clase derivada. le dará un error de tiempo de compilación. entonces java no te permitirá anular el método estático.
static
métodos static
no son heredados así que su copia separada del método de B
static
está relacionada con la class
no con el estado del Object