java中修饰权限的实质:在编译时起限制作用的协议,相当于一部分代码对新代码的添加起限制作用,编译通过后对已有代码无限制(无影响)。
调用成员变量的权限
(以下结论由于没有地方可供查询,都是我一一枚举出来的,因代码较繁冗不方便呈示。)
<由于public在什么情况下都可以调用,以下表格中忽略public>
- 用this和super调用的情况:
this.调用 | super.调用 | 用属于“同一包中类”的对象名调用 | 用属于“不同包中类”的对象名调用 | 所调用的成员在“对象名所属类”中定义 | 所调用的成员在“对象名所属类”的父类中定义 | 这一父类在相同包 | 这一父类在不同包 | prot | / | priv |
---|---|---|---|---|---|---|---|---|---|---|
是 | 是 | √ | √ | √ | ||||||
是 | 是 | 是 | √ | √ | × | |||||
是 | 是 | 是 | √ | × | × |
- 用对象名调用的情况
对于匿名对象,将new出的类当做“对象名所属类”即可;其他情况下,“对象名所属类”可认为是定义式左边的类;
ab lei = new abc();
比如以上命令行中的对象名所属类指的是ab这个类,可以直接当成
ab lei = new ab();
来判断,方法如果被重写则必然调出abc()中重写的方法。
2.1. 用对象名调用,
且调用“非继承或是重写的成员”的情况:
this.调用 | super.调用 | 用属于“同一包中类”的对象名调用 | 用属于“不同包中类”的对象名调用 | 所调用的成员在“对象名所属类”中定义 | 所调用的成员在“对象名所属类”的父类中定义 | 这一父类在相同包 | 这一父类在不同包 | prot | / | priv |
---|---|---|---|---|---|---|---|---|---|---|
是 | 是 | √ | √ | √/× | ||||||
是 | 是 | × | × | × |
2.2. 用对象名调用,
且调用“‘继承父类且没有重写’的成员”的情况:
this.调用 | super.调用 | 用属于“同一包中类”的对象名调用 | 用属于“不同包中类”的对象名调用 | 所调用的成员在“对象名所属类”中定义 | 所调用的成员在“对象名所属类”的父类中定义 | 这一父类在相同包 | 这一父类在不同包 | prot | / | priv |
---|---|---|---|---|---|---|---|---|---|---|
是 | 是 | 是 | √ | √ | × | |||||
是 | 是 | 是 | √/× | × | × | |||||
是 | 是 | 是 | √ | × | × | |||||
是 | 是 | 是 | × | × | × |
(“√/×”表示的是若在对象名所属类的方法中进行调用则可行,若在其他同包类的方法中调用则不可行)
对于匿名对象,将new出的类当做“对象名所属类”即可;其他情况下,“对象名所属类”可认为是定义式左边的类;
ab lei = new abc();
比如以上命令行中的对象名所属类指的是ab这个类,可以直接当成
ab lei = new ab();
来判断,方法如果被重写则必然调出abc()中重写的方法。
调用成员变量的权限
总结:
- public修饰的成员一律可调用;
- “所调用protected成员的代码要与进行调用的命令行同处一包”或者“进行调用的命令行在所调用protected成员所在类的子类中”;
- 所调用无修饰(friendly)成员,进行调用的命令行以及对象名所属类及所调用成员的相关父类乃至父类的父类等必须处于同一包中;
- 所调用private成员,进行调用的命令行都必须在对象名所属类当中。
重写的权限
若父类成员权限不够,则子类无法重写父类方法,即使名称一致也无法实现多态时重写方法的特殊调用——从父类方法无条件跳到子类重名方法,会导致方法的多态调用“失效”,只能调用被重写的父方法。
若父类与子类处于相同包:
public方法 | protected方法 | /方法 | private方法 |
---|---|---|---|
可重写 | 可重写 | 可重写 | 不可重写 |
若父类与子类处于不同包:
public方法 | protected方法 | /方法 | private方法 |
---|---|---|---|
可重写 | 可重写 | 不可重写 | 不可重写 |
代码示例:
package draft;
import draft2.新实验2;
public class 新实验 {
public static void main(String[] args) {
新实验 aaa=new 新的();
新实验 bbb=new 新实验2();
aaa.abc();
aaa.ab();
aaa.bc();
aaa.ac();
System.out.println();
bbb.abc();
bbb.ab();
bbb.bc();
bbb.ac();
}
private void abc() {
System.out.println("I am private father");
}
void ab() {
System.out.println("I am friendly father");
}
protected void bc() {
System.out.println("I am protected father");
}
public void ac() {
System.out.println("I am public father");
}
}
class 新的 extends 新实验{
private void abc() {
System.out.println("I am private son");
}
void ab() {
System.out.println("I am friendly son");
}
protected void bc() {
System.out.println("I am protected son");
}
public void ac() {
System.out.println("I am public son");
}
}
package draft2;
import draft.新实验;
public class 新实验2 extends 新实验 {
private void abc() {
System.out.println("I am private son");
}
void ab() {
System.out.println("I am friendly son");
}
protected void bc() {
System.out.println("I am protected son");
}
public void ac() {
System.out.println("I am public son");
}
}
console:
I am private father
I am friendly son
I am protected son
I am public son
I am private father
I am friendly father
I am protected son
I am public son
new对象与继承/引用的权限
public类 | /类 | |
---|---|---|
实例化包内的类 | √ | √ |
实例化包外的类 | √ | × |
public类 | /类 | |
---|---|---|
继承/引用包内的类 | √ | √ |
继承/引用包外的类 | √ | × |