2009-12-23 7 views
2
class BaseClass { 
    private void f() { 
     System.out.println("Baseclass f()"); 
    } 

    public static void main(String[] args) { 
     BaseClass dc = new DerivedClass(); 
     dc.f(); 
    } 
} 

class DerivedClass extends BaseClass { 
    public void f() { 
     System.out.println("DerivedClass f()"); 
    } 
} 

À mon avis, le courant continu objet fait référence à un seul devrait avoir méthode non-dérogation - méthode public void f(), qui en font (la méthode publique) invisible refered à BaseClass avec reference.Since la object dc referes to n'a pas la méthode privée f(), car DeriverClass ne peut pas hériter de la méthode private, comment l'objet dc peut-il se référer à call méthode f()?Java: Pourquoi la méthode de classe de base peut-elle appeler une méthode inexistante?

merci.

+2

Pourquoi diable déclarez-vous une variable d'une classe dérivée dans une méthode d'une classe de base? o 0 – Amber

+2

Je trouve ce genre de code dans Thinking in Java. Je pense que c'est un exemple valable pour creuser dans le cœur du langage de programmation Java. – Jichao

+0

Vous parlez de 'public void f()'. Cela ne se produit dans aucune des classes. Est-ce une méthode fictive? A quelle classe appartiendrait-il alors? – BalusC

Répondre

1

Quatre points:

(1) Pour des précisions sur ce vivyzer écrit, le code compile parce que la méthode principale BaseClass a accès à ses propres méthodes privées de la classe. Si vous avez écrit le code en tant que:

class BaseClass { 
    private void f() { } 
} 

class DerivedClass { 
    public void f() { } 
} 

class Bystander { 
    public static void main() { 
    BaseClass inst = new DerivedClass(); 
    inst.f(); 
    } 
} 

Ensuite, le code ne compilerait pas.

(2) Ceci est autorisé par le langage pour supporter l'usecase où l'auteur d'une classe de base peut ajouter une nouvelle méthode privée sans se soucier des types dérivés d'autres auteurs.

(3) Vous ne verrez pas ceci si la méthode n'était pas privée. Si le f() de la classe de base avait un paquet ou une visibilité protégée, alors la méthode serait une méthode virtuelle.

(4) L'inverse du point # 2 n'est pas supporté par Java. Plus précisément, si une classe dérivée a une méthode privée et qu'une nouvelle version du type de base introduit une méthode non privée avec la même signature, la classe dérivée et la nouvelle classe de base ne peuvent pas être utilisées ensemble. Il existe d'autres langages (par exemple C#) qui répondent plus complètement à ces sortes de questions de développement générationnel et générationnel. Si vous êtes intéressé par cet aspect, c'est une bonne lecture sur Artima: Versioning, Virtual, and Override

+0

La classe DerivedClass doit étendre BaseClass. – Jichao

3

Juste pour garder les choses droites, DerivedClass (DC) hérite private void f() de BaseClass (BC). Cette méthode héritée n'est pas accessible à DC mais elle est là car toute méthode appelée dans la partie BC de DC doit avoir accès à tout BC. Ainsi, lorsque vous convertissez DC en BC, la méthode héritée devient disponible. Maintenant, parce que vous exécutez le code à l'intérieur de la classe BC, il peut accéder à tous les membres privés de BC. Si vous avez déplacé le principal vers DC, il ne devrait pas compiler et encore moins fonctionner.

1

La méthode principale est à l'intérieur de BaseClass et les méthodes privées sont visibles. Si main est dans une autre classe, elle ne sera pas compilée.

3

Une idée fausse commune (ish) est que privé est par instance plutôt que par classe.

Par exemple:

class Foo 
{ 
    private int a; 

    public bar(final Foo other) 
    { 
     other.a = 5; 
    } 
} 

Certaines personnes ont l'impression que le code ci-dessus ne devrait pas fonctionner parce que « a » est « privé ». Ce n'est pas le cas, n'importe quelle instance de Foo peut accéder aux variables/méthodes privées de n'importe quelle autre instance de Foo. "private" signifie simplement que les instances d'autres classes (autres que Foo dans ce cas) ne peuvent pas accéder aux membres privés.

+1

Pourquoi Java autorise-t-il ce type de syntaxe? – Jichao

+3

Parce qu'il est techniquement dans la même portée. – BalusC

+1

C++ fait la même chose ... Je ne connais pas de langage qui offre une protection au niveau de l'objet (ça ne veut pas dire qu'il n'y en a pas, il y en a beaucoup que je ne connais pas :-). – TofuBeer

Questions connexes