Java类保护成员行为背后的逻辑

时间:2018-04-18 19:42:07

标签: java protected access-modifiers

可以请某人向我解释一下这个特殊事实背后的逻辑(不是行为本身而是逻辑),我认为,通过继承只允许通过子类型的引用来访问受保护的类成员,包括方法和字段 - 而不是通过声明受保护成员的父类型的引用 - 如果子类位于不同的包中?

如果父类和子类都在同一个包中,那么通过继承调用也只允许选项吗?

为什么不允许它从另一个继承树(C)访问另一个类(B)的受保护方法?

2 个答案:

答案 0 :(得分:1)

  

访问受保护的类成员< ...>仅允许通过继承,即通过子类型的引用 - 而不是通过声明受保护成员的父类型的引用 - 以防子类位于不同的包中?

这是因为protected表示从子类或相同包中访问。从不同的类中,您只能从同一个包访问成员。这就是你需要使用子类引用引用成员的原因。

  

如果父类和子类都在同一个包中,那么继承调用是否也只允许选项?

如果调用者在同一个包中 - 您可以使用任何引用(父或子)

  

为什么不允许从不同的继承树(C)访问另一个类(B)的受保护方法?

代码很高兴看到,但根据我对问题的理解,这正是protected修饰符需要做的事情。

答案 1 :(得分:1)

在实现某些功能时,您通常会希望减少“攻击面”并且不会暴露实现细节。这就是需要不同访问级别的原因。 protected的原因是继承。我们需要比public更严格的东西(隐藏实现细节),但不如private那么严格 - 以便子类可以访问。

我认为JLS §6.6.2. Details on protected Access最能解释这种逻辑:

  

对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。

我认为这应该解释“类,包,子类在相同或不同的包中”的逻辑:

  • 类应该清楚,类本身当然应该可以访问其成员。
  • 子类(相同或不同的包)也是可以理解的。
  • 包不是那么合乎逻辑,说实话。可能的解释:可能在同一个包中的其他类将用于实现此对象。

我同意protected有点不合逻辑。它结合了对水平访问(此包/其他包)的限制以及对垂直访问(子类/非子类)的限制。

  

如果父类和子类都在同一个包中,那么通过继承调用也只允许选项吗?

没有。来自同一个包的其他类也可以访问此类的受保护成员。

  

为什么不允许从不同的继承树(C)访问另一个类(B)的受保护方法呢?

这特别是protected的意图。这样做是为了隐藏A与“外部世界”的实现细节。