从子类访问父类的私有实例变量?

34
假设我们有一个类 foo,它有一个私有实例变量 bar
现在我们再有另一个类 baz,它 extends foo。如果在 foo 中没有定义访问器方法,那么 baz 中的非静态方法能否访问 foo 的变量 bar
顺便说一下,我正在使用 Java。
11个回答

37
不可以,根据java语言规范第3版

6.6.8 示例:private字段、方法和构造函数

私有类成员或构造函数只能在包含该成员或构造函数的顶级类(§7.6)的内部访问。它不会被子类继承。

但是尽管有这种语言限制,你可以通过反射访问私有字段和方法

Field privateStringField = 
   MyClass.class.getDeclaredField("privateString");
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);

可以在实例变量上使用protected关键字。 - sdfsdf
Super使用了你的解决方案,向库中添加了一个函数。 - Steve Moretz
感谢@Wim。如果有人想要复制粘贴测试,这里有一个基于完整类的示例:https://coding-stream-of-consciousness.com/2019/06/11/java-get-parent-class-private-variable-in-sub-class/。 - John Humphreys
注意:如果超类和子类都在同一顶级类的范围内,您可以访问超类的 private 成员。 - Andreas

24

不行,这种情况下应该使用protected关键字。


5
实际上,如果私有变量在类的未来版本中被移除,您应该使用受保护的 setter。 - jmucchiello

6

2
要在子类中使用超类的私有变量,需要使用访问器方法。否则,请改用protected修饰符代替private。

1

子类无法访问私有成员(这也是私有访问控制的全部意义所在)。


1

...如果foo中没有定义访问器方法怎么办?

你需要访问器。此外,要注意继承,那个变量真的应该在父类中吗?记得进行IS-A检查。


1

你不能在子类中访问私有变量。通常情况下,你应该使用“protected”或“package”(默认)级别的访问权限。但是,如果你想要非常巧妙地解决问题,你可以使用反射和AccessibleObject来获取它。

我不建议在生产代码中这样做,除非你真的陷入困境;对于测试等情况,这是可以接受的。


0

子类的实例中存在(继承)私有成员。由于子类的对象也是超类的对象,但对于子类来说不可见

它们可以通过超类的非私有方法间接访问。这些方法可以访问和操作私有成员


0

类的私有变量在该类内部具有作用域。如果必须在子类之间共享,则应将其声明为“protected”。


0

不,bar变量对于baz来说是不可访问的。bar变量应该是受保护的或公共的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接