Je sais que nous ne pouvons pas remplacer les méthodes statiques en Java, mais quelqu'un peut-il expliquer le code suivant?
class A {
public static void a() {
System.out.println("A.a()");
}
}
class B extends A {
public static void a() {
System.out.println("B.a()");
}
}
Comment ai-je pu remplacer la méthode a()
dans la classe B
?
Vous n'avez rien ignoré ici. Pour voir par vous-même, essayez de mettre l'annotation @Override
Avant public static void a()
dans la classe B
et Java générera une erreur.
Vous venez de définir une fonction dans la classe B
appelée a()
, qui est distincte (sans aucune relation) de la fonction a()
dans la classe A
.
Mais comme B.a()
a le même nom qu'une fonction de la classe parente, elle cache A.a()
[As pointé par l'ing. Fouad]. Au moment de l'exécution, le compilateur utilise la classe réelle de la référence déclarée pour déterminer la méthode à exécuter. Par exemple,
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.
Vous ne pouvez pas remplacer les méthodes statiques en Java. N'oubliez pas que les méthodes et les champs static
sont associés à la classe et non aux objets. (Bien que, dans certaines langues comme Smalltalk, cela soit possible).
J'ai trouvé de bonnes réponses ici: Pourquoi Java ne permet pas de remplacer les méthodes statiques?
Cela s'appelle hiding a method
, comme indiqué dans le Java tutorial Overriding and Hiding Methods :
Si une sous-classe définit une méthode de classe avec la même signature qu'une méthode de classe dans la superclasse, la méthode dans la sous-classe masque celle de la superclasse.
Les méthodes static
ne sont pas héritées, donc la copie séparée de la méthode de son B
static
sont liés à class
et non à l'état de Object
Vous n'avez pas remplacé la méthode a()
, car les méthodes static
ne sont pas héritées. Si vous aviez mis @Override
, vous auriez vu une erreur.
A.Java:10: error: method does not override or implement a method from a supertype
@Override
^
1 error
Mais cela ne vous empêche pas de définir des méthodes statiques avec la même signature dans les deux classes.
De plus, le choix de la méthode à appeler dépend du type déclaré 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 le système se souciait de l'identité de b
, il lancerait un NPE
. et en (2), la valeur de a
est ignorée. Puisque a
est déclaré comme A
, A.a()
est appelé.
Votre méthode n'est pas une méthode remplacée. vous essayez simplement de mettre l'annotation @Override avant votre méthode dans la classe dérivée. cela vous donnera une erreur de temps de compilation. donc Java ne vous permettra pas de remplacer la méthode statique.
Bien que la réponse goblinjuice ait été acceptée, je pensais que l'exemple de code pourrait être amélioré:
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");
}
}
Produit:
A
B
-
A
B
-
A
Si B avait remplacé print()
, il aurait écrit B sur la dernière ligne.
Les méthodes statiques seront appelées par son nom de classe, nous n'avons donc pas besoin de créer d'objet de classe, nous l'appelons simplement avec le nom de classe afin que nous ne puissions pas remplacer statique
par exemple
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
}
}
nous l'appelons simplement
AClass.test();
signifie que la classe statique ne peut pas être remplacée si elle est remplacée, alors comment l'appeler.