包访问权限:
这是默认的访问权限,没有任何关键字
意味着:假设一个类的成员被设置为包访问权限,当前包中的所有其他类都可以访问该成员,但对于这个包之外的所有类,该成员无法被访问。由于一个编译单元只能属于一个包,所以经包访问权限,处于同一个编译单元的所有类彼此之间都是自动可访问的。
取得某成员的访问权的途径:
- 使该成员访问权限为public,无论是谁,无论在哪里,都可以访问。
- 不加访问权限修饰词(即包访问权限)该成员,将其他需要访问该成员的类置于同一个包内,于是包内的其他类就可以访问该成员。
- 使用继承,继承而来的类既可以访问public成员,也可以访问protected成员(但不能访问private成员)。只有两个类都处于同一个包内时,它才可以访问包访问权限的成员。
- 提供getXXX()和setXXX()方法,以读取和改变数值。
public:
public修饰的成员对每个人都是可用的
private:
除了包含该成员的类之外,其他任何类都无法访问这个成员
任何可以肯定只是该类的一个“助手”方法的方法,都可以把它指定为private,以确保不会在包内的其他地方误用它,同样也防止改变或删除这个方法。
例子:当你编写的类不希望别人直接创建对象时,可以使用private修饰构造器
/* * 不能通过构造器来创建Sundae对象,而必须调用makeASundae()来创建 */ class Sundae{ private Sundae(){} static Sundae makeASundae(){ return new Sundae(); } } public class IceCream { public static void main(String[] args) { //! Sundae x = new Sundae(); Sundae x = Sundae.makeASundae(); } }
protected:
继承访问权限
基类把某个特定成员,使得它的子类可以访问该成员,而其他类不能访问,这时需要使用protected。protected也提供包访问权限,也就是说,相同包内的其他类可以访问protected元素。
例子:
package access.cookie2; public class Cookie { public Cookie(){ System.out.println("Cookie constructor"); } //若使用包访问权限,那么它的子类(不在同一个包中)无法调用该方法 protected void bite(){ System.out.println("bite"); } }
package access; import access.cookie2.Cookie; public class ChocolateChip2 extends Cookie{ public ChocolateChip2(){ System.out.println("ChocolateChip2 constructor"); } public void chomp(){ bite(); } public static void main(String[] args) { ChocolateChip2 x = new ChocolateChip2(); x.chomp(); } } /*output: Cookie constructor ChocolateChip2 constructor bite */
类的访问权限(不包含内部类):
- 包访问权限
- public
如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建该类的对象,但是,你需要在该类的static成员内部创建该对象。
ackage access; class Soup1{ private Soup1(){} public static Soup1 makeSoup(){ return new Soup1(); } } class Soup2{ private Soup2(){} private static Soup2 ps1 = new Soup2(); public static Soup2 access(){ return ps1; } public void f(){} }
/*
Soup2用到单例设计模式,因为你始终只能创建它的一个对象。Soup2类的对象是作为Soup2的一个static private成员而创建的,所以有且只有一个,而且除非是通过public方法access(),否则是无法访问到它的。
*/
public class Lunch { void testPrivate(){ // 因为其构造器是private的,所以不能直接new一个对象 //! Soup1 soup = new Soup1(); } void testStatic(){ Soup1 soup = Soup1.makeSoup(); } void testSingleton(){ Soup2.access().f(); } }
注意:
如果没能为类访问权限指定一个访问修饰符,它默认得到包访问权限。也就是说,该类的对象可以由包内任何其他类来创建,但在包外则不行。相同目录下的所有不具有明确package声明的文件,都被视作是该目录下默认包的一部分。如果该类的某个static成员是public,则客户端程序员依然可以调用该static成员,尽管他们并不能生成该类的对象。