2017-09-28 16 views
3

Quelqu'un peut-il me clarifier. Ici, la méthode d'instance est surchargée mais la variable ne l'est pas. sortie est: B 10Héritage avec une variable en Java

class A{ 
    int i=10; 
    public void name(){ 
     System.out.println("A"); 
    } 
} 

class B extends A{ 
    int i=20; 
    public void name(){   
     System.out.println("B"); 
    } 
} 

public class HelloWorld { 
    public static void main(String[] args){  
     A a = new B(); 
     a.name(); 
     System.out.println(a.i); 
    } 
} 
+3

Les appels de méthode sont liés _dynamically_ (ce qui signifie qu'ils sont résolus au moment de l'exécution) alors que les accès aux variables d'instance sont liés _statically_ (ce qui signifie qu'ils sont résolus au moment de la compilation). Et le compilateur utilise toujours le type _declared_ d'une variable pour résoudre ses variables d'instance. – Seelenvirtuose

+0

@Seelenvirtuose +1 pour cette explication simple et agréable – procrastinator

+0

Oui, vous avez raison. Pour accéder à une variable de la classe ou une instance est utilisé le getstatic ou getfield, le bytecode ne trouve pas la super classe, mais invoque le La méthode qui remplace sa méthode de superclasse exécutera invokevirtual, le bytecode trouvera la méthode de superclasse. – dabaicai

Répondre

1

Vous ne pouvez pas remplacer l'attribut, vous ne pouvez remplacer la méthode:

public class A{ 
    private int i=10; 

    public void name(){ 
     System.out.println("A"); 
    } 

    public int getI(){ 
     return i; 
    } 
} 

public class B extends A{ 
    private int i=20; 

    public void name(){   
     System.out.println("B"); 
    } 

    @Override 
    public int getI(){ 
     return i; 
    } 
} 

public class HelloWorld { 

    public static void main(String[] args){ 
     A a = new B(); 
     a.name(); 
     System.out.println(a.getI()); 
    } 

} 

Dans votre exemple, vous définissez la variable a que le type A donc la valeur i dans B est ignorée.

+0

Merci mon frère. Est-ce expliqué ici? –

+0

Vous pouvez commencer [ici] (https://stackoverflow.com/a/4716335/4906586) en sachant qu'il est plus que commun d'avoir vos attributs privés et de les exposer via des getters. Afterword, vous pouvez remplacer les getters comme vous le souhaitez dans les sous-classes – Al1

4

Vous êtes tout à fait correct. Les méthodes sont remplacées dans Java si la liste des paramètres et les noms de fonctions sont identiques et si les types de retour sont covariant.

i dans la classe de base est tout simplement Ténébreux: a.i fait référence au membre i dans la classe de base, puisque le type de la référence a est un A, même si elle fait référence à une instance B.

+0

@SiddappaWalake: oui vous pouvez l'appeler la classe Super aussi: je préfère le terme classe de base car je suis un gars C++ vraiment. – Bathsheba

+0

Mais pourquoi c'est étrange ici ??. Les variables sont également des membres d'instance? –

+0

@SiddappaWalake: En effet, ils le sont, mais le comportement des champs de classe et des méthodes de classe diffère à cet égard. – Bathsheba

1

En Java, les variables d'instance ne peuvent pas être remplacées, seules les méthodes peuvent être remplacées. Lorsque nous déclarons un champ avec le même nom que déclaré en super classe, ce nouveau champ cache le champ existant. Voir ce document Java Hiding Fields.