2009-11-15 5 views
3
class A { 
    public void talk(){ 
     this.sayIt(); 
    } 

    private void sayIt(){ 
     System.out.println("class A says..."); 
    } 
} 

class B extends A { 
    private void sayIt(){ 
     System.out.println("class B says..."); 
    } 
} 

classe test, méthode principale:héritage Java - s'il vous plaît expliquer

B b = new B(); 
b.talk() 

//output 
class A says... 

Je ne peux pas obtenir ce depuis:

classe B hérite de classe A, le membre du public et ne peut pas voir/hériter de la fonction privée. Donc, dans classe B, nous pourrions appeler talk(). // puisqu'il est hérité par la classe parente.

Maintenant, dans la méthode de conversation() , il y a un appel à Sayit() depuis Sayit() est défini dans classe B,

Je me attends un appel à B.sayIt() à exécuter lorsque this.sayIt() est exécuté.

Est-ce que "ceci" ne fait pas référence à la classe B?

Veuillez expliquer.

+0

Cette méthode 'talk' est pas en classe' B'. –

Répondre

6

En tant que tel, vous avez deux définitions de sayIt() plutôt qu'une seule qui est remplacée par une sous-classe.

A l'intérieur d'une section de code de classe A, il appellera toujours la version de la classe A, même si la version de classe B était protégée ou publique. En effet, la classe A ne connaît que la version de la classe A car la version de la classe B est et non un remplacement, mais une méthode complètement différente qui partage le même nom. Alors qu'il est à l'intérieur d'une section de code de classe B, il appellera toujours la version de la classe B puisque la version de la classe A est marquée private. Comme mentionné par d'autres, si vous changez la définition en protected ou public, elle sera visible à la classe B et fera ce que vous voulez. Notez que si vous utilisiez la visibilité par défaut (package), les règles de portée deviendraient très complexes et les résultats réels varieraient selon les sous-classes du même package et celles qui sont dans des sous-classes différentes.

3

Envisagez de créer protected au lieu de private sur sayIt. sayIt sur B ne surcharge pas sayIt sur A.

+1

Merci, mais comment appelle-t-on A.sayIt() puisqu'il n'est pas visible du contexte de B? – Andreas

+0

Depuis sayIt est privé, la JVM sait que lorsque talk appelle sayIt, il n'a pas besoin de regarder dans les sous-classes pour la version substituée de sayIt, donc il fait l'appel direct le A.sayIt(). –

+0

Il n'est pas appelé depuis B, mais à partir d'une méthode implémentée dans la classe A, qui peut voir les méthodes privées dans la classe A. –

0

Si vous changez la méthode "sayIt" à protéger, cela fonctionnera comme vous le souhaitez.

Il semble que vous soyez un peu confus sur la façon dont cela fonctionne avec les méthodes prioritaires. Si je ne me trompe pas, ce que vous essayez de faire est parfaitement bien en C++, mais pas en Java.

2

Vous essayez de remplacer les méthodes privées. Cela n'a aucun sens.

0

Oui « ce » de b.talkIt() se réfèrent à la classe B, mais depuis sayIt() est privé dans A et talkIt() est decalred dans A et non redéfinie dans B, le sayIt() sera appelé celui de A.

Vous peut regarder de cette façon. sayIt() de A est privé, donc il ne peut pas être remplacé. Comme il n'est pas écrasé, sayIt() appel par les méthodes de A pointera toujours vers celui connu de A (car il n'est pas surchargé).

Espérons que cela aide.

0

"Cela ne fait-il pas référence à la classe B?" - Non. Bien que vous créiez l'instance de la classe B, vous vous référez toujours à la méthode du type de base qui est talk(). Une façon d'atteindre ce même objectif est d'utiliser le modèle template-method.

/BB

0

Parce que Sayit est une méthode privée, il est en fait pas substituée. Une façon de comprendre cela consiste à ajouter l'annotation @Override à toute méthode qui, selon vous, remplace quelque chose de la superclasse. Si vous avez tort (comme dans ce cas), le compilateur vous le dira.

0

Parce que dans talk vous reffer à this.sayIt et objet B est une instance de A.

Objet A n'a pas connaissance des méthodes B. Faire l'objet A une classe abstraite avec sayIt méthode abstraite que vous appelez dans un discours ou changer la visibilité de sayIt.

En outre - utiliser annotaions et IDE vous avertira avec des avertissements.

0

Selon Java spécification du langage 8.4.8:

A class C inherits from its direct superclass and direct superinterfaces 
all non-private methods (whether abstract or not) of the superclass and 
superinterfaces that are public, protected or declared with default access 
in the same package as C and are neither overridden nor hidden by a 
declaration in the class. 

Alors B n'a pas hérité A.sayIt() et donc ne pas l'ignorer. Étant donné que vous avez défini sayIt() comme étant privé, la classe B ne peut pas l'ignorer car elle a été définie comme suit:

Questions connexes