类、属性字段、方法均要有访问权限控制,Java为我们提供了四种访问权限控制符。下面对这些访问权限控制符进行介绍。
一、default
默认访问权限没有关键字,但通常指包访问权限。这意味着当前的包中的所有其他类对那个成员都有访问权限。但对于这个包之外的所有类,这个成员是不可用的。
包访问权限为类群聚在一个包中的做法提供了意义和理由。
下面例子演示包访问权限方法不可跨包访问情况。
这个例子中,classC c=new classC();能编译成功的原因是类的修饰符是public
c.f(); 出现编译异常的原因是classC中f()函数是包访问权限,在classB(包外)不可访问。
默认访问权限使得程序员无法访问包访问权限成员(因为在不同包里)。这种权限的好处是在程序员忘记加权限的情况下,能够自动得到权限。
二、public
public修饰的成员对每个人都是可用的。
将"一、default"的例子中classC的f()访问修饰符改为public,则在包外的classB中访问则能编译通过。
三、private
除了包含该成员的类之外,其他任何类(具体指同包类或不同包类)都无法访问这个成员。
一个类中某个对象的引用是private,并不代表其他对象无法拥有该对象的public引用。通过下面例子对这句话进行理解:
package package2;
public class Soup {
private Soup(){}
//一个类中对象的引用是private
private static Soup sp=new Soup();
//其他对象可以拥有该对象的public引用
public static Soup getInstance(){
return sp;
}
public void f(){}
}
属性字段一般都是private,若要对其访问,会提供了getter/setter方法。
若类中的某个方法只是在其他方法的内部使用,并不希望外部使用,则将此方法用private修饰。
四、protected
考虑下面的情况,a.f2()会报编译异常(因为不同包)。若要通过编译,一种方法是将f1()用public修饰符修饰,但这种方法把权限放到了最大。Fruit希望其派生类无论同包或异包都能访问其成员(这也符合继承的特性),与Fruit无关的类只可使用public方法。
package package1;
public class Fruit {
public void f1(){}
void f2(){
}
}
package package2;
import package1.Fruit;
public class Apple extends Fruit {
public static void main(String[] args) {
Apple a=new Apple();
a.f1();
a.f2();
}
}
现在终于知道protected是解决什么问题的了。(知其所以然很重要,共勉)
protected提供了派生类访问权限和包访问权限
下面用一张表总结这四种访问权限的用法