当前位置: 首页 > 知识库问答 >
问题:

了解类中受保护成员的行为

莫承运
2023-03-14

我试图理解类中受保护成员的行为。我有一个类TopClass,其中包含受保护的整数pr

类别:

package com.test;

import com.test.anotherpackage.SubClass1;
import com.test.anotherpackage.SubClass2;
import com.test.anotherpackage.SubClass3;

public class TopClass {
    protected int pr;

    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 3;
        s1.pr = 0;
        s2.pr = 1;
        s3.pr = 1;
    }
}

还有另一个包com.test.anotherpackage,它有3个类SubClass1SubClass2SubClass3。继承层次结构如下:

  1. 子类1扩展了TopClass

第1子类

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass1 extends TopClass {

    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; // Error because not in same package.
        s1.pr = 0; //(1)
        s2.pr = 1; // Does not throw an Exception. Why? (2)
        s3.pr = 1; // (3)
    }
}

子课堂

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass2 extends SubClass1 {
    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; // Error because not in same package.
        s1.pr = 0; // Throws Exception, why?  (4)
        s2.pr = 1; //  (5)
        s3.pr = 1; // Does not throw an Exception. Why?(6)
    }
}

第3子类

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass3 extends SubClass2 {
    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; 
        s1.pr = 0; // Not Visible (7)
        s2.pr = 1; // Not Visible (8)
        s3.pr = 1; // (9)
    }
}

在上述代码中,(1)(2)(3)(5)(6)(9)工作正常,没有任何可见性问题。但是(4)(7)(8)存在可见性问题。

根据JLS§6.6.2.1,

让C是声明受保护成员的类。只允许在C的子类S的主体内进行访问。

此外,如果Id表示实例字段或实例方法,则:

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

如果通过字段访问表达式E.Id(其中E是主表达式)或方法调用表达式E.Id(…)进行访问,如果E是主表达式,则当且仅当E的类型是S或S的子类时,才允许访问。

我在这里试图理解的是,如果表达式Q的类型是S或S的子类出现在图片中,为什么会出现。是否有任何特定场景可以使此实现受益?任何相关的例子都将受到高度赞赏。我试着这样看,但找不到一个解释来解决我的疑问。


共有1个答案

房学
2023-03-14

您正在讨论的表达式也是代码中对您的问题负责的表达式:

如果表达式Q的类型是S或S的子类

(2)因为表达式s2的类型是SubClass1
的子类(4)因为表达式s1的类型不是SubClass2
(5)因为表达式s3的类型是SubClass2的子类

然而,我不知道

这种实现可能有益的任何特定场景

要么。

 类似资料:
  • 问题内容: 我为SCJP做准备,我也知道受保护成员的作用域在包中以及在其他包中(在某些情况下,例如只有继承才可能)。 例如:我有三个类作为Parentclass Childclass Friendclass 这背后的原因是什么,在Friendclass中,成员x将不接受为其分配值,而对于Childclass而言,它充当私有成员。 问题答案: 您甚至无法访问,因为具有默认可见性(不受保护)。参见ht

  • 我正在阅读这本Java SCJP的书,我偶然发现了以下内容: 但是我得到了这个错误: 那么,出什么问题了?

  • 我在package1中有一个名为a的类,在Package2中有另一个名为C的类。C类扩展了A类。 A有一个实例变量,声明如下: 这是怎么回事?

  • 问题内容: 我想对此进行一些讨论,但无法推断出我的情况的答案。仍然需要帮助。 这是我的代码: 在上面的示例中,下面的一些定义似乎令人困惑: 问题: 为什么我不能从子类实例(对象)访问受保护的成员()? 问题答案: 作为声明类的子类的其他包中的类只能访问其自己的继承成员。 …但不是其他对象的继承成员。

  • 问题内容: 为什么在最终课程中允许受保护的成员? 这不应该是编译时错误吗? 编辑:正如人们指出的那样,您可以使用默认修饰符来获得相同的程序包访问权限。它的行为应该完全相同,因为protected是默认+子类,而final修饰符明确地拒绝了子类,因此我认为答案不只是提供相同的程序包访问。 问题答案: 该改性剂是必要的方法其覆盖从基类的方法,在没有那些构件暴露于所述。 通常,您可以引入很多不必要的规则

  • 问题内容: 我在派生类中创建了基类的实例,并尝试访问受保护的成员。 我可以直接访问派生类中的受保护成员,而无需实例化基类。 基类: 同一包中的派生类- 不同包中的派生类- 当派生类也位于同一包中,而派生类位于不同包中时,如何使用基类的实例访问派生类中基类的受保护成员呢? 如果我将受保护的成员标记为“静态”,则可以使用驻留在不同包中的派生类中的基类实例来访问基类的受保护成员。 问题答案: 没错,您是