【问题标题】:Are private fields inherited by the subclass?子类是否继承了私有字段?
【发布时间】:2011-11-16 13:40:10
【问题描述】:

我了解到子类不能继承私有字段或方法。然而,在这个例子中

class SuperClass {
    private int n=3;
    int getN() {
        return n;
    }
}

class SubClass extends SuperClass {
    public static void main(String[] args) {
        SubClass e = new SubClass();
        System.out.println("n= " + e.getN());
    }
}

当我运行main 时,我得到的输出为n=3。看来SubClass 是从SuperClass 继承私有属性n

所以,请解释一下这里发生了什么。谢谢。

【问题讨论】:

标签: java inheritance private-members


【解决方案1】:

子类“拥有”其超类的字段,但不能直接访问它们。同样,子类“拥有”私有方法,但您不能直接从子类调用或覆盖它们。

Java documentation on inheritance,它说

子类继承其父类的私有成员。

但是,我发现将其视为更有用

子类继承其父类的私有成员,但无权访问它们

但这归结为语义学。

【讨论】:

  • 好的..但有一点疑问,因为“子类继承了其父类的私有成员但无权访问它们”为什么我们使用 INHERITANCE 而只是我们可以在某个地方实例化一个对象同一个包,可以访问属性..
  • 在许多情况下,委托(通过公共方法访问属性)更可取。但是,对于polymorphism,尤其是在使用Template pattern 时,您需要子类化(尽管使用接口通常更好)。
【解决方案2】:

您正在继承并使用 getn() 方法,该方法是包私有的,可从子类获得(因为在这种情况下,两者本质上都在同一个包中。)您不能直接访问 n,因为它是私人的。可以访问n 的是getn() 方法,因为它与n 在同一个类中,并且您可以访问getn() 方法,因为它不是私有的。

如果你这样做了:

System.out.println("n= "+e.n+"");

...代替您当前的行,那么由于上述原因它不会编译。

通过 setter / getter 方法公开私有变量是完全正常的行为,这基本上就是您在这里所做的。不同之处在于,使用这种方法,您有可能在获取或设置变量时检查/限制/更改/记录/任何变量的值,并且在代码编译时您可以这样做而无需进行重大更改。如果您只是公开一个字段并让人们直接访问它,您就不能这样做。

【讨论】:

    【解决方案3】:

    这是一个值得讨论的话题。产生混淆的原因是,从技术上讲,子类继承了私有字段,因为私有字段存在于子类中,所以当您调用 getN() 时,它会返回 n 的值。所以字段 n 存在于子类中。如果它不存在,那么当你调用 getN() 时,它会发出错误,因为字段 n 不存在。问题是,它确实存在,并且由于它是在超类中声明的,因此从技术上讲它是由子类继承的。

    但是,我们(Java 程序员和关于继承的 java 官方文档)不考虑这种继承。按照我们的约定,这不被视为继承,因为您不能直接访问这些字段的值。就好像它们不是你的一样,因为访问它们的唯一方法是使用其他人(不是该超类的子类的类)使用的东西(getter/setter)。

    因此,从概念上讲,私有字段不是继承的(尽管它们存在于子类中)。

    我认为教师应该比他们更清楚地说明这一点。仔细看了之后,真的是一头雾水。

    【讨论】:

      【解决方案4】:

      子类只能通过publicprotected访问方法(getter、setter)访问超类的私有字段。

      尝试直接访问私有变量,发现不行:例如

      // won't work
      System.out.println("n= "+e.n+"");
      

      【讨论】:

        【解决方案5】:

        这将无法编译:

        class NewExample extends Example {
            public static void main (String[] args) {
                NewExample e = new NewExample();
                System.out.println("n=" + e.n);
            }
        }
        

        因为变量被声明为private,子类不能直接访问它。与方法相同。如果您将getn() 声明为private,您也无法访问它。如果你想让一个子类直接访问n,你可以将它声明为protected int n,这样子类就可以直接修改它。在很多情况下,这可能是可取的,也可能是不可取的。

        【讨论】:

          【解决方案6】:

          这是因为子类的对象正在访问父类中非私有的方法。该方法 getN() 正在返回父类的私有属性。这就是继承父类的私有属性值的原因。我希望这有帮助!

          【讨论】:

            【解决方案7】:

            这是一个很棒的话题,它把我和我的教授拖入了争吵。但他耐心地向我解释,证明了他的勇气。

            可访问性与继承无关。无论访问修饰符如何,所有属性和方法都由子类继承。

            虽然子类不能访问属性或方法,但还是继承了它们!

            每种编程语言对上述继承和可访问性概念都有自己的解释。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-01-04
              • 1970-01-01
              • 2019-04-26
              • 1970-01-01
              • 2011-03-23
              • 2012-05-16
              • 2018-06-14
              相关资源
              最近更新 更多