【问题标题】:Can not access protected member in a sub-class which is also a sub-class无法访问子类中的受保护成员,该子类也是子类
【发布时间】:2011-10-16 06:31:56
【问题描述】:

这是 A Programmer's Guide to Java™ SCJP Certification A Comprehensive Primer - Third Edition - Khalid A. Mughal Rolf W. Rasmussen 中的一个示例明白。

我知道如果我们不将受保护的成员继承到另一个包中定义的子类中,我们将无法访问它。

但是我还是不明白为什么我们不能从子类的子类中访问它。

示例如下

A.java

package packageA;
public class A {
    protected int z;
}

B.java

package packageB;

import packageA.A;

public class B extends A {

    void action(A obj1, B obj2, C obj3) {
        z = 10;      // z in B - Works
        obj1.z = 10; // Won't work for obvious reason
        obj2.z = 10; // z in B - Works
        obj3.z = 10; // z in C - Works

    }
}

class C extends B {

    void action(A obj1, B obj2) {
        z = 10; // Works
        obj1.z = 10; // Won't work for obvious reason
        obj2.z = 10; // z in B - WHY DOESN'T THIS WORK?????

    }
}

【问题讨论】:

  • 这是一个学术练习还是你真的想写这样的代码?
  • @jiggy 这是Java™ SCJP 认证程序员指南综合入门第三版 Khalid A. Mughal Rolf W. Rasmussen 中的一个示例,我无法理解。
  • 我当然希望作者不要使用诸如“A”、“B”之类的类名来给出示例。如果他们这样做的话就不是很直观!

标签: java oop scope


【解决方案1】:

受保护的成员只能被声明它的类的子类与受保护的类相同的包中的类访问成员被声明。在您的情况下,B 类和 C 类在与 A 类的不同包中声明。这就是为什么您不能通过对 A 类的引用访问“z”的原因。如果将 B 类和 C 类移到与 A 相同的包中,它将工作。

这就是为什么您不能在 C 类中访问 obj2.z 的原因,因为“z”是在不同包中的类中声明的。

【讨论】:

  • 这是否意味着第二个子类中没有继承成员访问权限?
  • 我想我不能像编译器那样思考。
  • 如果您正在为 SCJP 学习(就像我所做的那样),当您看到受保护的成员时,请考虑使用“Package and Kids”进行访问。换句话说,只有同一个包中的子类和类才能访问受保护的成员,句号。祝你学习顺利。
【解决方案2】:

当前接受的答案不回答问题。它解释了为什么您不能从BC 的正文中访问A 实例的成员z。但问题是为什么你不能从C 中访问B 实例的成员z

原因是B 不是C 的子类。阅读 Java 规范,第 6.6.2.1 节:

令 C 为声明受保护成员的类。只允许在 C 的子类 S 的主体内访问。

另外,如果Id表示实例字段或实例方法,那么:

如果通过限定名称 Q.Id 进行访问,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型为 S 或S的子类。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1

(粗体字)

所以在B 内你可以说obj3.z,因为obj3C 类型,而CB 的子类。

但是在C 中你不能说obj2.z,因为obj2B 类型,而B不是C 的子类。


总结一下protected的含义:

假设在类 A 的主体中声明了一个受保护的成员。

(1) 您可以从包含A 的包中的任何位置访问受保护的成员。

(2) 此外,在不同包中定义的A 的子类S 可以访问S 实例或从S 继承的类实例上的受保护成员,但是不在 S 继承的类的实例上。

最后一个子句是回答这个问题的关键。

【讨论】:

    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 2013-06-08
    • 2012-07-22
    • 2016-07-05
    • 2011-02-18
    • 2013-10-22
    • 2010-09-16
    相关资源
    最近更新 更多