在“ Java的一些句子 ”一文中,我写道: “受保护的方法和字段可以在同一包中的类中使用(到目前为止与私有包相同),此外,还可以从其他类中使用受保护的方法和字段,这些类扩展了包含受保护的字段或方法。”
尽管以上陈述是正确的,但它可能无法揭示全部事实,我认为这值得一新。
当您在一个类中有一个专用X(方法,字段,类,接口,构造函数)时,可以从顶级类中使用该X。 如前一篇文章所述,使用意味着可以在实例“ this
”中访问X,而在其他实例中,只要代码访问与X在同一顶级类中,就可以访问X。
如果删除X前面的private
关键字,则将可见性扩展到程序包级别。 您可以在包中使用X,就像在私有的类中使用X之前一样。
如果我们再走一步,并在X的前面插入关键字protected
,它将在扩展了声明X的类的类中可见,但无法从该类内部以私有X或从内部打包private的方式访问同一方式。相同的包装。 由于protected
扩展了私有包对X的可见性,因此,仍然可以以相同的方式在包内使用受保护的X,但在包外不能以相同的方式使用。
不同之处在于,您只能在扩展X功能的代码中访问受保护的X。
以上不是精确的定义。 我在此博客中多次引用的Java语言规范在6.6.2章中对此进行了详细说明。 精确,完整,但阅读起来可能不容易或有趣,这对本文也可能是正确的,但是由于您正在阅读,所以我认为您觉得它很有趣,很有教育意义,或者您有一些非常特定的原因来阅读它。
当您与声明X的类位于同一包中时,可以在其他实例上访问X。 我们可以有一些简单的类来演示这一点。 首先,我们可以有一个扩展的根类:
package a;
public class A {protected void protectedMethod(A a) { }
}
我们有类“ B”,它扩展了“ A”,并且在同一包中。
package a;
import a.A;
public class B extends A {@Overrideprotected void protectedMethod(A a) {a.protectedMethod(this);super.protectedMethod(this);}
}
如果我们将类“ B”移动/复制到另一个包,例如:
package b;
import a.A;
public class B extends A {@Overrideprotected void protectedMethod(A a) {a.protectedMethod(this);super.protectedMethod(this);}
}
那么第6行将无法编译。 在前一个程序包中时,编译器允许它访问该方法,因为程序包保护使其成为可能。 无论在什么实现实例中,方法的参数“ a”都在同一包中。 在“ b.B”类的情况下,程序包保护不允许访问,并且因为我们存储在方法参数“ a”中的实际对象实例可能是“ b.B”未扩展的类的实例,因此无法访问它。 它可以是该类示例的实例:
package c;
import a.A;
public class C extends A { }
您可以做的是:
- 覆盖子类中的方法或
- 使用关键字
super
调用父方法。
通常,这实际上是您可以使用其程序包外部的受保护方法来做的所有事情。
翻译自: https://www.javacodegeeks.com/2015/01/fine-points-of-protection.html