11
votes

Héritage dans les méthodes statiques

Pourquoi le code ci-dessous imprime "MAIN"?

public class Main
{
    public static void method()
    {
        System.out.println("Main");
    }

    public static void main(String[] args)
    {
        Main m = new SubMain();
        m.method();
    }
}

class SubMain extends Main
{
    public static void method()
    {
        System.out.println("SubMain");
    }
}


2 commentaires

Vous pouvez même écrire MAIN M = NULL; puis appelez la méthode, l'expression avant que le point ne soit pas utilisé du tout.


Et si nous n'avions pas de méthode remplacée dans la sous-classe "SUMINAINE" et utilisez SUMINAIN M = Nouveau SUMENMAIN (); M.Method ();


5 Réponses :


19
votes

Les méthodes statiques sont résolues sur le type de compilation de la variable. m est de type principal , donc la méthode dans principale est appelée.

Si vous le modifiez à SUMINAIN M ... , la méthode sur SUMINAIN sera appelée.


3 commentaires

En plus de cette réponse, je vous recommande de ne pas appeler des méthodes statiques à partir d'un objet d'instance et appelez-les à partir du nom de la classe (ex: SubMainMain.Method () plutôt que m.Method ()).


C'est pourquoi Java vous avertit lorsque vous essayez d'invoquer une méthode statique sur un objet d'instance.


@Ricfitting Java ne vous avertit pas mais votre IDE peut vous avertir.



2
votes

Eclipse me donne ce type d'avertissement lorsque j'essaie de faire ce genre de chose:

La méthode statique XXX () à partir du type XXX doit être accessible de manière statique

Les méthodes statiques ne participent pas à l'héritage. La variable est de type principale , de sorte que le compilateur a résolu votre appel de fonction sur main.method () . .

Pour plus de plaisir, essayez de paramétrer m à null .


0 commentaires

15
votes

C'est parce que les méthodes statiques ne sont pas polymorphes. De plus, la méthode statique doit être invoquée non par objet, mais à l'aide de la classe, c'est-à-dire main.Method () ou submain.method () . Lorsque vous appelez m.method () java appelle en réalité main.method () parce que m est de type principal.

Si vous voulez profiter du polymorphisme, n'utilisez pas de méthodes statiques.


0 commentaires

1
votes

Java effectue une liaison anticipée pour des méthodes statiques, contrairement aux méthodes d'instance liées de manière dynamique.

Parce que votre variable d'objet est de type principal, l'appel est lié à la mise en œuvre de la superclasse lors de la compilation.

Une bonne explication est disponible ici .


0 commentaires

0
votes

Les méthodes statiques sont statiquement liées à leur nom de classe car M est le type de classe principale puis après la compilation, cela ressemblerait comme suit Main.Method (); Après la compilation de votre classe Exécutez la commande suivante Javap -c Main vous pouvez voir le code d'assemblage JVM pour la classe principale et tu verrais la suite M.Method // invoque statique invoquer static, invocation SPÉCIALE dit que la liaison statique INVOKE SPÉCIALE, INVOKE Interface indique cette liaison dynamique


0 commentaires