2010-03-17 2 views

Répondre

23

Parce que l'héritage est destiné à modifier le comportement. Le comportement est exposé par des méthodes, et c'est pourquoi ils peuvent être remplacés.

Les champs ne sont pas un comportement mais un état. Vous n'avez pas besoin de modifier cela, ni les méthodes privées employées par la superclasse. Ils sont destinés à permettre à la superclasse de faire son travail.

28

Vous pouvez masquer un champ, mais pas outrepasser il. Le masquage signifie qu'un champ aura une valeur différente selon la classe à laquelle il a accédé. Le champ de la sous-classe "cachera" le champ dans la super-classe, mais les deux existent.

C'est une pratique extrêmement mauvaise pour cacher le terrain, mais fonctionne:

public class HideField { 

    public static class A 
    { 
     String name = "a"; 

     public void doIt1() { System.out.println(name); }; 
     public void doIt2() { System.out.println(name); }; 
    } 

    public static class B extends A 
    { 
     String name = "b"; 

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

    public static void main(String[] args) 
    { 
     A a = new A(); 
     B b = new B(); 

     a.doIt1(); // print a 
     b.doIt1(); // print a 
     a.doIt2(); // print a 
     b.doIt2(); // print b <-- B.name hides A.name 
    } 
} 

Selon que la méthode a été outrepassée, le champ dans A ou B est accessible.

Ne faites jamais ça! Ce n'est jamais la solution à votre problème et crée des bugs très subtils liés à l'héritage.

+0

Oh pour les upvotes multiples pour le conseil impératif de ne pas faire cela. C'est un peu comme un seigneur maléfique se transformant en serpent ... Cela n'aide jamais. –

+0

Il y a des raisons subtiles pour lesquelles vous aimeriez: en particulier avec les champs de classe statique auxquels vous accédez en utilisant spécifiquement le nom de super ou de sous-classe. "Jamais" n'est jamais une bonne chose à dire;) – RichieHH

+0

L'utilisation de static est totalement autre chose, Oracle a la même suggestion avec @ewernli: http://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html – MengT

1

Parce que:

  • Il peut briser le code parent class. Par exemple, considérons le code suivant (Quel serait le comportement de la ligne obB.getInt(); dans le code suivant si, variables d'instance prépondérants est autorisé):

    class A 
    { 
        int aInt; 
    
        public int getInt() 
        { 
         return aInt; 
        } 
    } 
    
    class B extends A 
    { 
        int aInt; 
    
        public int getInt2() 
        { 
         return aInt; 
        } 
    
        public static void main(String[] args) 
        { 
         B obB = new B(); 
    
         //What would be behavior in following line if, 
         //instance variables overriding is allowed 
         obB.getInt(); 
        } 
    } 
    
  • Il n'est pas logique parce child class devrait avoir/refléter tous les comportements de parent class.

Ainsi, vous ne pouvez cacher les méthodes/variables héritées dans child class mais ne peut pas override.

Voici un extrait de Java doc from Oracle spécifiant quelle opération vous pouvez effectuer/attendre de child class:

Vous pouvez utiliser les membres hérités est, les remplacer, les cacher, ou de les compléter avec de nouveaux membres :

  • Les champs hérités peuvent être utilisés directement, comme tous les autres champs.
  • Vous pouvez déclarer un champ dans la sous-classe avec le même nom que celui de la superclasse, le masquant (non recommandé).