一、Java中有四种访问权限,private、default(一般省略)、public、protected。
private: Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
default:即不加任何访问修饰符,通常称为“默认访问权限“或者“包访问权限”。该模式下,只允许在同一个包中进行访问。
protected: 介于public 和 private 之间的一种访问修饰符,一般称之为“保护访问权限”。被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包访问。
这里需要注意的是,所谓的访问,可以分为两种不同方式:第一,通过对象实例访问;第二,直接访问。
比如说,某父类protected权限的成员,子类是可以直接访问的,换一种说话是子类其实继承了父类的除了private成员外的所有成员,包括protected成员,所以与其说是子类访问了父类的protected成员,不如说子类访问了自己的从父类继承来的protected成员。另一方面,如果该子类与父类不在同一个包里,那么通过父类的对象实例是不能访问父类的protected成员的。
二、下面用表格来展示四种修饰符的访问权限范围:
权限 | 类内 | 同包 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
default | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
三、距离说明
在Eclipse中新建个类,四个类的结构如下,DemoA和DemoB 是同包的类,DemoC和DemoD是同包的类,DemoC 继承了DemoA。
DemoA类的定义如下,有四个成员变量,权限分别为private、default、protected、public。四个成员方法,权限分别为 private、default、protected、public。
package cn.com.tes1;
public class DemoA {
private String S1="a";//private修饰的成员变量
String S2="b";//默认修饰符修饰的成员变量
protected String S3="c";//protected修饰的成员变量
public String S4="d";//public修饰的成员变量
//private修饰的成员方法
private void getS1() {
System.out.println(S1);
}
//默认修饰符修饰的成员方法
void getS2() {
System.out.println(S2);
}
//protected修饰符修饰的成员方法
protected void getS3() {
System.out.println(S3);
}
//public修饰符修饰的成员方法
public void getS4() {
System.out.println(S4);
}
}
DemoB类定义如下,它和DemoA类同属于 cn.com.tes1包 ,在里面定义了一个成员方法 (),该方法通过两种方法对DemoA类的所有成员进行了访问,第一方法通过实例化一个DemoA类对象对成员变量及方法进行访问,第二种是直接访问DemoA中的成员。通过IDE的自动检测报错,可以看出,DemoB类是不能直接访问DemoA类的成员的,但通过对象的方法可以访问default权限以下(default、protected、public)的成员,DemoB可以访问除private以为的成员方法。
package cn.com.tes1;
/**
* 与DemoA同包
* @author Administrator
*
*/
public class DemoB {
public void show() {
DemoA da = new DemoA();
//调用成员变量 (实力化对象访问 引用.方式调用)
System.out.println(da.S1);//S1修饰符为private,同包不能访问
System.out.println(da.S2);//S2修饰为默认修饰符,同包可以访问
System.out.println(da.S3);//S3修饰为protected,同包可以访问
System.out.println(da.S4);//S4修饰符为public,同包可以访问
//调用成员变量 (直接调用成员方法)
System.out.println(S1);//S1修饰符为private,同包不能访问
System.out.println(S2);//S2修饰为默认修饰符,同包不能访问
System.out.println(S3);//S3修饰为protected,同包不能访问
System.out.println(S4);//S4修饰符为public,同包不能访问
//直接调用成员方法
getS1();//S1修饰符为private,同包不能访问
getS2();//S2修饰为默认修饰符,同包不能访问
getS3();//S3修饰符为protected,同包不能访问
getS4();//S4修饰符为public,同步不能访问
//调用成员方法(实力化对象访问 引用.方式调用)
da.getS1();//S1修饰符为private,同包不能访问
da.getS2();//S2修饰为默认修饰符,同包可以访问
da.getS3();//S3修饰符为protected,同步可以访问
da.getS4();//S4修饰符为public,同步可以访问
}
}
DemoC类定义如下,它和DemoA类属于不同的包,但是DemoC继承了DemoA,在里面定义了一个成员方法show(),该方法同样通过两种方法对DemoA类的所有成员进行了访问,第一方法通过实例化一个DemoA类对象aa对成员变量及方法进行访问,第二种是直接访问DemoA中的成员。通过IDE的自动检测报错,可以看出,DemoC类是可以直接访问DemoA类权限为protected、public的成员(因为子类的缘故),但通过对象的方法只能访问 public权限的成员(因为DemoC和DemoA不同包)。
package cn.com.tes2;
/**
* 与DemoA不同包,继承DemoA
*/
import cn.com.tes1.DemoA;
public class DemoC extends DemoA{
DemoC(){
super();
}
public void show() {
DemoA da = new DemoA();
//调用成员变量 (实力化对象访问 引用.方式调用)
System.out.println(da.S1);//S1修饰符为private,子类不同包不能访问
System.out.println(da.S2);//S2修饰为默认修饰符,子类不同包不能访问
System.out.println(da.S3);//S3修饰为protected,子类不同包不能访问
System.out.println(da.S4);//S4修饰符为public,子类不同包可以访问
//调用成员变量 (直接调用成员变量)
System.out.println(S1);//S1修饰符为private,子类不同包不能访问
System.out.println(S2);//S2修饰为默认修饰符,子类不同包不能访问
System.out.println(S3);//S3修饰为protected,子类不同包可以访问
System.out.println(S4);//S4修饰符为public,子类不同包可以访问
//直接调用成员方法
getS1();//S1修饰符为private,子类不同包不能访问
getS2();//S2修饰为默认修饰符,子类不同包不能访问
getS3();//S3修饰符为protected,子类不同包可以访问
getS4();//S4修饰符为public,子类不同包可以访问
//调用成员方法(实力化对象访问 引用.方式调用)
da.getS1();//S1修饰符为private,子类不同包不能访问
da.getS2();//S2修饰为默认修饰符,子类不同包不能访问
da.getS3();//S3修饰符为protected,子类不同包不能访问
da.getS4();//S4修饰符为public,子类不同包可以访问
}
}
}
DemoD类定义如下,它是DemoA类不同包的一般类,在里面定义了一个成员方法show(),该方法同样通过两种方法对DemoA类的所有成员进行了访问,第一方法通过实例化一个DemoA类对象aa对成员变量及方法进行访问,第二种是直接访问DemoA中的成员。通过IDE的自动检测报错,可以看出,DemoD类是不可以直接访问DemoA类的成员(因为不是子类的缘故),但通过对象的方法只能访问 public权限的成员(因为DemoD和DemoA不同包)。
package cn.com.tes2;
import cn.com.tes1.DemoA;
/**
* 与DemoA不同包
* @author Administrator
*
*/
public class DemoD {
public void show() {
DemoA da = new DemoA();
//调用成员变量 (实力化对象访问 引用.方式调用)
System.out.println(da.S1);//S1修饰符为private,不同包不能访问
System.out.println(da.S2);//S2修饰为默认修饰符,不同包不能访问
System.out.println(da.S3);//S3修饰为protected,不同包不能访问
System.out.println(da.S4);//S4修饰符为public不,不同包可以访问
//调用成员变量 (直接调用成员方法)
System.out.println(S1);//S1修饰符为private,不同包不能访问
System.out.println(S2);//S2修饰为默认修饰符,不同包不能访问
System.out.println(S3);//S3修饰为protected,不同包不能访问
System.out.println(S4);//S4修饰符为public,
//直接调用成员方法
//直接调用成员方法
getS1();//S1修饰符为private,不同包不能访问
getS2();//S2修饰为默认修饰符,不同包不能访问
getS3();//S3修饰符为protected,不同包不能访问
getS4();//S4修饰符为public,不同包不能访问
//调用成员方法(实力化对象访问 引用.方式调用)
da.getS1();//S1修饰符为private,不同包不能访问
da.getS2();//S2修饰为默认修饰符,不同包不能访问
da.getS3();//S3修饰符为protected,不同包不能访问
da.getS4();//S4修饰符为public,不同包可以访问
}
}