java - 访问子类对象自己的私有(private)字段

标签 java inheritance subclass private-members

刚发现这个构造不编译:

class A {
    private int data;
    public static int process(B b) {
        return b.data;// error here: 'data has private access in A'
    }
}
class B extends A {}

当然这个问题可以很容易地手动解决(将 b 转换为 A,使字段 protected 等)。但问题是,为什么java不允许这样构造呢?我认为编译器必须知道 B 是 A 的子类,因此 A 的方法必须能够访问 A 的私有(private)字段。

我能想到的唯一可能的问题是,如果 B 有自己的“数据”字段,编译器肯定不知道我们要访问哪个字段,但这就是继承的目的,对吧?

最佳答案

嗯,编译器不允许,因为语言规范不允许。 JLS section 8.3 (字段声明)指定(强调我的):

A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class.

A private field of a superclass might be accessible to a subclass - for example, if both classes are members of the same class. Nevertheless, a private field is never inherited by a subclass.

所以查找字段作为子类的成员(6.5.6.2)必须失败 - 编译器在解释失败的原因上略有帮助,而不仅仅是说该成员不存在,但我相信从纯粹的意义上说,查找应该只是说“Type B没有名为 data 的成员,而不是提示它不可访问。

至于为什么语言是这样设计的——我不确定。 C# 中的等效代码很好,对我来说非常有意义。例如,在 C# 5 规范中,第 3.4 节:

When a type inherits from a base class, all members of the base class, except instance constructors, destructors and static constructors, become members of the derived type. The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn't an instance constructor, static constructor, or destructor. However, an inherited member may not be accessible in a derived type, either because of its declared accessibility (§3.5.1) or because it is hidden by a declaration in the type itself (§3.7.1.2).

关于java - 访问子类对象自己的私有(private)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26043819/

相关文章:

java - 如何在 Android 的宽 RadioButton 小部件中居中 RadioButton 图形?

c++ - 较大类中的两个类共享数据

winapi - 如何子类化 win32 控件并保持与旧版本 comctl32.dll 的兼容性?

oop - 单例子类

java - 为什么这个用于从多行条目中挑选项目的正则表达式不起作用?

java - 有效的多边形碰撞检测

java - UTF 到 EBCDIC 的转换是无损的吗?

java 父类(super class)有多个构造函数

c# - 在虚方法的所有覆盖之后执行代码

识别父类(super class)构造函数的 Javadoc