web-dev-qa-db-fra.com

Méthodes privées en héritage

Voici un extrait de code intéressant:

public class Superclass {

    public static void main (String[] args){
        Superclass obj = new Subclass();
        obj.doSomething(); #prints "from Superclass"
    }

    private void doSomething(){System.out.println("from Superclass");}
}

class Subclass extends Superclass {

    private void doSomething(){System.out.println("from Subclass");}

}

Je sais que les sous-classes n'héritent pas des membres privés de son parent, mais obj parvient ici à appeler une méthode à laquelle il ne devrait pas avoir accès. Au moment de la compilation, obj est du type Superclass, au moment de l'exécution, du type Subclass. 

Cela a probablement quelque chose à voir avec le fait que l'appel à doSomething () a lieu dans la classe du pilote, qui se trouve être sa propre classe (et pourquoi il est possible d'appeler doSomething () en premier lieu). 

La question se résume donc: comment obj a-t-il accès à un membre privé de son parent?

12
Victor Cheung

Vous avez répondu vous-même. Comme les méthodes privées ne sont pas héritées, une référence de superclasse appelle sa propre méthode privée.

13
Swapnil

Les méthodes privées ne sont que pour le propriétaire.

Pas même pour les enfants, les parents ou les amis du propriétaire.

15
Alex Kreutznaer
Superclass obj = new Subclass();

À ce stade, obj est à la fois un objet Subclass et un objet Superclass. Le fait que vous utilisiez Superclass dans la déclaration de la variable consiste simplement à la convertir.

Quand vous faites: obj.doSomething(), vous demandez au compilateur d’appeler la méthode privée doSomething() de obj. Parce que vous le faites depuis la méthode statique principale dans Superclass, le compilateur peut l'appeler. 

Si vous utilisiez la méthode principale de Subclass plutôt que celle de Superclass, vous ne pourrez pas accéder à cette méthode car, comme vous l'avez dit, elle n'est ni héritée ni comprise dans votre définition de Subclass.

Donc, fondamentalement, vous avez bien compris l'héritage. Le problème était lié à la visibilité des méthodes privées.

5
Pauls

Cela fonctionne parce que vous lancez dans une Superclass à partir d'une méthode de la Superclass. Dans ce contexte, Superclass.doSomething est disponible pour le compilateur.

Si vous deviez modifier vos super et sous-classes en deux classes différentes A et B, non liées à la classe contenant la méthode main, et essayer le même code, le compilateur se plaindrait de ne pas avoir accès à la méthode.

4

Quand vous avez utilisé cette ligne:

Superclass obj = new Subclass();

Vous avez converti Subclass en un objet Superclass, qui utilise uniquement les méthodes de la Superclass et les mêmes données. Si vous l'avez réintégré dans une sous-classe, vous pouvez utiliser à nouveau les méthodes de sous-classe, comme suit:

((Subclass)obj).doSomething(); #prints "from Subclass"
3
EAKAE

Etant donné que le type de référence de l'objet obj est SuperClass, un appel à doSomething() tente d'accéder à la méthode privée définie dans SuperClass (les méthodes privées ne peuvent pas être remplacées). Comme doSomething() est accessible dans SuperClass, la méthode main est accessible. doSomething() sans donner d'erreur/s.

J'espère que cela t'aides! :-)

3
learner

pourquoi il est possible d'invoquer doSomething () en premier lieu?

Pourquoi pas? obj est une instance de Subclass et Superclass, et comme doSomething() est déclaré dans Superclass et que obj y est utilisé, vous avez donc accès à Superclass.doSomething(), vous pouvez essayer de renommer votre méthode (en par exemple : doAnotherThing() ) et vous y aurez toujours accès.

comment obj a-t-il accès à un membre privé de son parent?

Il n'y a pas de parent/enfant pour une méthode privée, et comme obj est également un type de Superclass, il a donc accès à toutes les méthodes/champs privés déclarés, car obj est utilisé dans cette classe. Vous perdrez ce privilège d'accès si vous êtes en dehors de Superclass ou d'une classe dont Superclass est membre (classe imbriquée).

Alors quoi?

Il n'y a pas de relation/héritage entre les méthodes privées de SuperClass et les méthodes privées de SubClass, même si elles portent le même nom et la même signature, à partir de Java Language Specification, Java SE 8 Edition :

Une méthode privée et toutes les méthodes déclarées immédiatement dans une classe Finale (§8.1.1.2) se comportent comme si elles étaient définitives, car il est impossible De les ignorer.

1
O.Badr

Pour comprendre cette question, vous pouvez associer une méthode privée à une variable membre de la super classe et de la sous classe.

Nous savons donc que la variable membre ne sera pas remplacée par la sous-classe.

Par exemple:

Class A{
 int i = 10;
}

Class B extends A{
  int i = 11;
}

Class C extends A {
   int i = 12;
}

A a1 = new B();
print(a1.i) // Will print 10

A a2 = new B();
print(a2.i) // Will print 10 

De manière similaire, lorsqu'il n'y a pas de variable de référence d'héritage, la super classe sera prise en compte.

0
Devendra Dadhich