Java类的访问权限
1 类的访问权限
类的访问权限: 公共类, 非公共类
使用public修饰的类就是公共类, 没有使用public修饰就是非公共类
什么情况下定义为公共类?
如果这个类允许在其他包中使用就定义为公共类, 如果不允许在其他包中使用就不用public修饰
2 类成员的访问权限
访问权限 | 当前类 | 当前包 | 不在当前类中的派生类(子类) | 其他类 |
---|---|---|---|---|
私有的 private | 可以 | 不 | 不 | 不| |
默认的,没有权限修饰符 | 可以 | 可以 | 不 | 不| |
受保护的 protected | 可以 | 可以 | 可以 | 不| |
公共的 public | 可以 | 可以 | 可以 | 可以| |
规则:
1、如果想要在任意位置可以直接使用,就定义为public公共的
2、想要在当前类和派生类(子类)中直接使用, 就定义为protected受保护的
3、如果只想在当前包中使用, 就使用默认权限
4、如果只想在当前类中使用,就定义为private私有的
举例说明、包结构如下:
/**
* 在类中定义四个实例变量,分别设置不同的访问权限
*/
public class Father {
private int xx = 10; //私有的, 只能在当前类中使用
int yy = 20; //默认的, 可以在当前类/当前包
protected int zz = 30 ; //受保护的, 可以在当前类/当前包/派生类
public int qq = 40; //公共的, 可以在任意位置
//在当前类中的实例方法, 可以直接使用实例变量
public void m1() {
xx = 101;
yy = 202;
zz = 303 ;
qq = 404;
}
protected void xx(){
System.out.println("这是父类孩中的受保护方法");
}
}
/**
* 测试
* 访问当前包中Father类的四个实例变量
* 实例变量需要先创建对象, 通过对象名来访问
*
*/
public class Test01 {
public static void main(String[] args) {
Father f = new Father();
System.out.println( f.xx ); //私有的 . The field Father.xx is not visible
// xx字段(成员变量)不可见
System.out.println( f.yy ); //默认的
System.out.println( f.zz ); //受保护的
System.out.println( f.qq ); //公共的
}
}
/**
* 当前包是p2, 测试在p2包中访问p1包Father类的实例变量
*
*/
public class Test02 {
public static void main(String[] args) {
//先创建Father类的对象
Father f2 = new Father();
System.out.println( f2.xx ); //私有的 不能访问
System.out.println( f2.yy ); //默认的 不能访问
System.out.println( f2.zz ); //受保护的 不能访问
System.out.println( f2.qq ); //公共的
}
}
/**
* 在p3包中定义了Son类,继承了p1包中的Father类
* 子类继承了父类, 就自动拥有了父类所有的实例变量与实例方法
* Son类继承了Father类, 继承到了四个实例变量: xx, yy, zz, qq, 和一个实例方法 : m1()
*/
public class Son extends Father {
int ee;
public void sm() {
//子类的实例方法, 在实例方法中,可以直接使用实例变量
//Son类有四个实例变量: xx, yy, zz ,qq
//因为继承所有自动拥有这四个实例变量, 因为没有访问权限,所有xx/yy不能直接使用
xx = 103; //私有的,不能访问
yy = 203; //默认的,不能访问
zz = 303 ; //受保护的
qq = 403; //公共的
Son son = new Son();//通过对象调用实际上也是调用的子类的xx方法,子类继承了父类的受保护放放风可以直接使用
son.m1();
m1(); //子类继承父类,继承了父类的实例方法,父类的xx方法是受保护的可以直接使用
}
}
3 方法重写(覆盖)中的访问权限
方法覆盖的规则:
1)方法签名必须相同, 方法签名就是方法名与参数列表
2)方法返回值类型可以相同, 可以是父类方法返回值类型的子类型
3)访问权限可以相同,可以更宽泛(大)
4)子类方法不能抛出比父类方法更大的异常
public class Animal {
}
public class Dog extends Animal {
}
/**
* 创建一个类作为父类,
* 定义方法,在子类中重写
*
*/
public class Father {
public void m1(int x, int y) {
//方法签名是: m1(int, int )
}
protected Animal produce() {
return new Animal();
}
}
/**
* 定义子类继承父类
* 重写父类的方法
*
*/
public class Son extends Father {
@Override //注解,这个注解可以验证重写的是否正确
public void m1(int abc, int y) {
/*
* 1)方法签名必须相同 m1(int ,int )
* 2)返回值类型是void, 必须相同
* 3)父类方法访问权限是public,子类重写后也必须是public
*/
}
@Override
// protected Animal produce() {
public Dog produce() {
/*
* 1)方法签名必须相同: produce()
* 2)返回值类型可以相同, 也可以是父类方法返回值类型的子类型
* 3)访问权限,可以相同,也可以更大
*/
return new Dog();
}
}