子类是否继承私有字段?

2022-08-31 05:20:30

这是一个面试问题。

子类是否继承私有字段?

我回答“否”,因为我们无法使用“正常的OOP方式”访问它们。但是面试官认为它们是遗传的,因为我们可以通过间接或使用反射来访问这些字段,并且它们仍然存在于对象中。

回来后,我在javadoc中发现了以下引用:

超类中的私人成员

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

你知道面试官的观点有什么论据吗?


答案 1

这里问题/答案中的大多数混淆都围绕着继承的定义。

显然,正如@DigitalRoss所解释的那样子类的对象必须包含其超类的私有字段。正如他所说,无法访问私人成员并不意味着它不存在。

然而。这与类的继承概念不同。与Java世界的情况一样,存在语义问题,仲裁者是Java语言规范(目前是第3版)。

正如JLS所述(https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):

声明为私有的类的成员不会被该类的子类继承。只有声明为受保护或公共的类的成员才会由在包中声明的子类继承,而不是声明该类的包。

这解决了面试官提出的确切问题:“子是否继承私有字段”。(着重号由我补充)

答案是否定的。子类的对象包含其超类的私有字段。子类本身没有其超类的私有字段的概念。

它是迂腐性质的语义吗?是的。这是一个有用的面试问题吗?可能不是。但是JLS为Java世界建立了定义,并且(在这种情况下)明确地做到了这一点。

编辑(删除了Bjarne Stroustrup的平行引用,由于java和c ++之间的差异,可能只会增加混乱。我会让我的答案放在JLS:)


答案 2

是的

重要的是要认识到,虽然有两个类,但只有一个对象。

所以,是的,它当然继承了私有字段。据推测,它们对于正确的对象功能是必不可少的,虽然父类的对象不是派生类的对象,但派生类的实例通常肯定是父类的实例。如果没有所有的字段,就不可能很好。

不可以,您无法直接访问它们。是的,它们是遗传的。他们必须如此。

这是一个好问题!


更新:

呃,“不”

好吧,我想我们都学到了一些东西。由于JLS起源于确切的“未继承”措辞,因此回答“否”是正确的。由于子类无法访问或修改私有字段,因此换句话说,它们不会被继承。但实际上只有一个对象,它确实包含私有字段,因此,如果有人以错误的方式采用JLS和教程措辞,将很难理解OOP,Java对象以及真正发生的事情。

更新到更新:

这里的争议涉及一个根本性的模糊性:究竟在讨论什么?对象?还是我们在某种意义上谈论阶级本身?在描述类而不是对象时,允许很大的自由度。因此,子类不会继承私有字段,但作为子类实例的对象肯定包含私有字段。