可以请某人向我解释一下这个特殊事实背后的逻辑(不是行为本身而是逻辑),我认为,通过继承只允许通过子类型的引用来访问受保护的类成员,包括方法和字段 - 而不是通过声明受保护成员的父类型的引用 - 如果子类位于不同的包中?
如果父类和子类都在同一个包中,那么通过继承调用也只允许选项吗?
为什么不允许它从另一个继承树(C)访问另一个类(B)的受保护方法?
答案 0 :(得分:1)
访问受保护的类成员< ...>仅允许通过继承,即通过子类型的引用 - 而不是通过声明受保护成员的父类型的引用 - 以防子类位于不同的包中?
这是因为protected
表示从子类或相同包中访问。从不同的类中,您只能从同一个包访问成员。这就是你需要使用子类引用引用成员的原因。
如果父类和子类都在同一个包中,那么继承调用是否也只允许选项?
如果调用者在同一个包中 - 您可以使用任何引用(父或子)
为什么不允许从不同的继承树(C)访问另一个类(B)的受保护方法?
代码很高兴看到,但根据我对问题的理解,这正是protected
修饰符需要做的事情。
答案 1 :(得分:1)
在实现某些功能时,您通常会希望减少“攻击面”并且不会暴露实现细节。这就是需要不同访问级别的原因。 protected
的原因是继承。我们需要比public
更严格的东西(隐藏实现细节),但不如private
那么严格 - 以便子类可以访问。
我认为JLS §6.6.2. Details on protected Access最能解释这种逻辑:
对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。
我认为这应该解释“类,包,子类在相同或不同的包中”的逻辑:
我同意protected
有点不合逻辑。它结合了对水平访问(此包/其他包)的限制以及对垂直访问(子类/非子类)的限制。
如果父类和子类都在同一个包中,那么通过继承调用也只允许选项吗?
没有。来自同一个包的其他类也可以访问此类的受保护成员。
为什么不允许从不同的继承树(C)访问另一个类(B)的受保护方法呢?
这特别是protected
的意图。这样做是为了隐藏A
与“外部世界”的实现细节。