【问题标题】:Protected access modifier allows access field in not derived case受保护的访问修饰符允许在未派生的情况下访问字段
【发布时间】:2019-09-16 10:31:17
【问题描述】:

我在包bbb中有类c1

package bbb;

public class c1 {

     protected static  int a = 5;

}

我必须导入 c1 的类:

    package aaa;
    import bbb.c1;
    public class c2 extends c1 {

        public c2() {
            a = 10;
            c1 c = new c1();
            c.a = 60;
        }
    }


package aaa;
import bbb.c1;
public class c4 {

    public c4() {

        c1 c = new c1();
        c.a = 60;
    }
}

c2c4 都使用 c1c2 派生自 c1c4 - 不是。我对这两个类中的变量c 感兴趣。在c4 类的情况下,我有编译错误"a has protected access in bbb.c1" 而在c2 情况下c 变量工作正常。

我预计派生类可能会使用内部字段a,但不应允许在新创建的c 变量中使用它,就像它在c4 案例中所做的那样,因为事实上它不是通过派生访问字段。逻辑在哪里?

更新

Book Mala Gupta "OCA Java SE 8 Programmer I Certification Guide" 的引用告诉派生类对象只能通过继承而不是引用来访问受保护的方法:

默认访问可以与包私有(可访问 仅在一个包内),并且受保护的访问可以与包相比 private + kids(“kids”指派生类)。孩子们可以访问受保护的 方法只能通过继承而不是通过引用(通过 在对象上使用点运算符)

是不是搞错了?

【问题讨论】:

    标签: java


    【解决方案1】:

    c2 构造函数中允许访问受保护字段a,因为c2c1 的子类。来自JLS

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

    【讨论】:

      【解决方案2】:

      我认为这是人们普遍存在的误解。如果一个类可以访问它自己的属性(如 c1.a,在您的情况下),那么它可以访问同一类的另一个实例中的相同属性,而不管它的访问修饰符(甚至是私有的)。例如,这有效:

      class Base {
          private int x = 0;
      
          public void method(Base other) {
              other.x += 5;
          }
      }
      

      如果您想知道为什么,我想这就是它的设计初衷。我想其他支持面向对象设计的语言也一样(我知道它在 C++ 中也是如此)。

      注意:这与您的问题无关,但使用大写开头的单词(此处为 C1、C2、C4)命名您的类是一个很好的约定,以便其他人更容易阅读代码。

      【讨论】:

        【解决方案3】:
        public class c4 {
        
            public c4() {
        
                c1 c = new c1();
                c.a = 60;
            }
        }
        

        c1public,因此来自另一个包的c4 可以访问它。但是,变量c1.aprotected,这意味着它只对包bbbc1 的任何子项可见。所以,c.a = 60;CompileTimeError,因为c1.abbb 包中不可见,并且c4 没有扩展c1


        The official tutorial 可能对你有用。

        _______________________________________________________________________ | │ 类 │ 包 │ 子类 │ 子类 │ 世界 | | │ │ │(相同包装)│(不同包装)│ | |────────────┼────────┼──────────┼──────────┼──────── ──┼────────| |公开 │ + │ + │ + │ + │ + | |────────────┼────────┼──────────┼──────────┼──────── ──┼────────| |受保护 │ + │ + │ + │ + │ | |────────────┼────────┼──────────┼──────────┼──────── ──┼────────| |无修饰语│ + │ + │ + │ │ | |────────────┼────────┼──────────┼──────────┼──────── ──┼────────| |私人 │ + │ │ │ │ | |___________|_______|_________|__________|__________|________| +:可访问空白:不可访问

        【讨论】:

          猜你喜欢
          • 2013-03-05
          • 2016-12-11
          • 1970-01-01
          • 2014-12-29
          • 2013-04-03
          • 2019-05-07
          • 1970-01-01
          相关资源
          最近更新 更多