一直以来对package-private和protected它们的访问权限理解的并不是很深,于是今天到官网又温习了一遍它们的概念。
附上官网链接:
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
- public 和 package-private(不显示指定访问修饰符)是顶层(top-level )访问权限
- public, private, protected, or package-private (no explicit modifier).是成员级别(member-level)的访问权限
一个类可以用public修饰符来声明,这种情况会使这个对于任何在其它地方的类都是可见的。如果一个类没有修饰符(默认被叫做包私有(package-private))那么它只会对同一个包中的类是可见的。
在成员级别上,也可以和顶层类一样使用public或者包私有的修饰符,并且具有一样的意思。对于成员来讲,有两个额外的访问修饰符:private和protected。private 修饰符指定的成员只能在类中被访问。而protected修饰符不仅指定了成员可以在它所在包中的其它类能够访问,在其它包中的子类也可以访问。
访问修饰符如下表:
访问权限在两个方面上可以影响你。第一,你想使用来自其它来源的类,例如在Java平台中的类,访问等级决定了那些类的哪些成员能够被你的类访问。其次,当以写出一个类时,你需要决定在你的类中的每个变量和方法应该有怎样的访问等级。
看一下访问等级是如何影响可见性的:
Alpha的成员变量对其它类的访问权限如下表所示:
对于protected成员的访问可能存在疑惑。
问题原文:
http://stackoverflow.com/questions/9546208/why-cant-i-call-a-protected-method-from-an-inheriting-class-in-another-package
主要说的就是为什么在其他包的子类中并不能调用其它基类实例,或者其它子类实例的protected 方法。
代码如下:
package bg.svetlin.ui.controls;
public abstract class Control {
protected int getHeight() {
//..
}
//...
}
package bg.svetlin.ui.controls;
public abstract class LayoutControl extends Control {
public abstract void addControl(Control control);
//...
}
package bg.svetlin.ui.controls.screen;
public abstract class Screen extends LayoutControl {
//...
}
package bg.svetlin.ui.controls.screen.list;
public class List extends Screen {
private final Vector controls = new Vector();
public void addControl(Control control) {
//compile error
height += control.getHeight();
controls.addElement(control);
}
}
List类中并不能调用其它基类或是子类实例的protected方法,只可以使用自己从基类继承过来的成员。
根据StackOverflow得到最多赞的回答中提到的:SCJP(SCJP Oracle Certified programmer for java 5 study guide)的原文:
But what does it mean for a subclass-outside-the-package to have access to a superclass (parent) member? It means the subclass inherits the member. It does not, however, mean the subclass-outside-the-package can access the member using a reference to an instance of the superclass. In other words, protected = inheritance. The subclass can see the protected member only through inheritance.
其它包的子类能够访问父类的成员指的是:子类继承父类,并不意味着子类可以通过一个超类(super-class)实例的引用来访问这个实例的protected成员。这就意味着protected=inheritance,子类只能通过继承来看到并使用protected成员。