2010-03-17 70 views

回答

23

因为继承旨在修改行为。行为通过方法暴露,这就是为什么他们可以被覆盖。

字段不是行为而是状态。你不需要修改它,也不需要修改超类所使用的私有方法。它们的目的是让超类来完成它的工作。

28

你可以隐藏一个字段,但不是覆盖它。

隐藏意味着一个字段将有一个不同的值,具体取决于它访问哪个类。子类中的字段将“隐藏”超类中的字段,但都存在。

这是一个非常不好的做法隐藏的领域,但工作原理:

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 
    } 
} 

根据是否该方法AB重写,现场访问。

千万别这么做!这永远不会解决您的问题,并创建与继承有关的非常微妙的错误。

+0

哦,多个upvotes的强制性建议,不要做这个。这就像一个邪恶的霸主转变成一条蛇......它从来没有帮助。 – 2013-09-26 13:03:14

+0

有一些微妙的原因可能会导致您特别喜欢:特别是使用通过专门使用超级或子类名访问的静态类字段。 “永不”永远不是一件好事情;) – RichieHH 2014-05-14 15:20:12

+0

使用静态是完全另一回事,Oracle对@ewernli有相同的建议:http://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html – MengT 2014-10-03 08:08:27

1

因为:

  • 它可能会破坏parent class代码。例如,请考虑下面的代码(什么是在下面的代码行obB.getInt();的行为如果实例变量覆盖是允许的):

    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(); 
        } 
    } 
    
  • 这不是逻辑因为child class应该有/反映所有行为parent class

所以,你只能隐藏child class继承的方法/变量,但不能override

以下是Java doc from Oracle提取指定什么操作可以执行/从child class期待:

您可以使用继承的成员是,取代他们,隐藏起来,或者用新的成员来补充其不足:

  • 继承字段可以直接使用,就像任何其他字段一样。
  • 您可以在子类中声明一个与超类中相同名称的字段,从而隐藏它(不推荐)。