上篇文章 -- 笔记 20 补充说明了前四点,这里接着来说剩下的两点.
要点如下:
5. 访问权限修饰符可以修饰成员内部类
1). 访问权限修饰符对内部类的访问限制与外部类的一般成员遵循一样的规则,具体请参考 笔记 10 ;
2). 这里涉及到的子类是外部类的子类;
6. 访问权限修饰符可以修饰成员内部类的成员变量和成员方法
1). 成员内部类可由 4 种访问权限修饰符修饰,每种内部类的成员方法或变量也可由 4 种访问权限修饰符修饰,所以分 16 种情况来讨论;
2). 修饰类时涉及到的子类是外部类的子类;修饰内部类的成员方法或变量时涉及到的子类是成员内部类的子类;
3). 构造方法的默认修饰符与类一致;
4). 在外部类的不同包子类中创建 protected 修饰的内部类的对象时,会提示构造方法不可见,这时要为该内部类添加 public 修饰的构造方法;
作者: 蝉蝉
请尊重作者劳动成果,转载请在标题注明 "转载" 字样,并标明原文链接:
http://www.cnblogs.com/chanchan/p/8281021.html
下面详细展开说明.
类 Person 中定义了 4 个成员内部类,分别由 public,protected,默认,private 修饰;并给这 4 个成员内部类分别添加 4 个成员方法,分别由 public,protected,默认及 private 修饰.代码如下:
A. 根据访问权限修饰符的特性,要验证每种成员内部类的访问权限,需要分别在
public class InnerClassPu {
void printInCPuDef() {
System.out.println("public inner class:default");
}
public void printInCPuPu() {
System.out.println("public inner class:public");
}
protected void printInCPuPro() {
System.out.println("public inner class:protected");
}
private void printInCPuPri() {
System.out.println("public inner class:private");
}
}
protected class InnerClassPro {
void printInCProDef() {
System.out.println("protected inner class:default");
}
public void printInCProPu() {
System.out.println("protected inner class:public");
}
protected void printInCProPro() {
System.out.println("protected inner class:protected");
}
private void printInCProPri() {
System.out.println("protected inner class:private");
}
}
class InnerClass {
//访问权限修饰符修饰成员内部类的方法
void printInCDefDef() {
System.out.println("default inner class:default");
}
public void printInCDefPu() {
System.out.println("default inner class:public");
}
protected void printInCDefPro() {
System.out.println("default inner class:protected");
}
private void printInCDefPri() {
System.out.println("default inner class:private");
}
}
private class InnerClassPri {
void printInCPriDef() {
System.out.println("private inner class:default");
}
public void printInCPriPu() {
System.out.println("private inner class:public");
}
protected void printInCPriPro() {
System.out.println("private inner class:protected");
}
private void printInCPriPri() {
System.out.println("private inner class:private");
}
}
1). 外部类
2). 与外部类同一个包的类
3). 与外部类不同包的子类
4). 与外部类不同包的其他类
这 4 种类中添加测试代码.
注:
这里是把成员内部类当成外部类的一个成员来看的,即,成员内部类是一个整体,对其他类而言它就是外部类的一个变量而已,所以这里涉及到的子类是外部类的子类.
B. 另,根据访问权限修饰符的特性,要验证每种成员方法的访问权限,需要分别在
1). 外部类
2). 与成员内部类同一个包的类
3). 与成员内部类不同包的子类
4). 与成员内部类不同包的其他类
1>. 其他类是外部类的子类
2>. 其他类不是外部类的子类
这 5 种类中添加测试代码.
注:
1]. 这里要测试的是成员内部类的成员方法,所以对情况 3 而言,应该是成员内部类的子类,而不是外部类的子类;
又由于成员内部类位于外部类的内部,所以其子类是不可能位于其他包中的,所以第 3 种情况是不存在的.
2]. 由于成员内部类是外部类的一个成员,其可见性对 "与其不同包的"" 外部类的子类和非子类 " 是不一样的,所以情况 4 要再细分成两种情况.
综合上面的 A,B,下面几个图是所有的测试代码:
其中 Person 是外部类,TestMain 是同包的类,GateMan 是不同包的 Person 的非子类,Teacher 是不同包的 Person 的子类.
1.Person 内的测试:
由上图可知:
所有成员内部类对外部类都可见;
所有成员内部类的所有成员方法对外部类都可见;
2.TestMain 内的测试:
由上图可知:
private 修饰的成员内部类对与外部类同包的其他类是不可见的;
private 修饰的成员内部类的所有成员方法对与内部类同包的其他类是不可见的;
public,protected 及默认权限的成员内部类对与外部类同包的其他类是可见的;
public,protected 及默认权限的成员内部类的 public,protected 及默认权限的成员方法对与内部类同包的其他类是可见的;
public,protected 及默认权限的成员内部类的 private 权限的成员方法对与内部类同包的其他类是可见的;
3.GateMan 内的测试:
由上图可知:
public 修饰的成员内部类对与外部类不同包的非子类是可见的;
public 修饰的成员内部类的 public 权限的成员方法对与内部类不同包的非子类是可见的;
public 修饰的成员内部类的其他权限的成员方法对与内部类不同包的非子类是不可见的;
protected,默认及 private 修饰的成员内部类对与外部类不同包的非子类是不可见的;
protected,默认及 private 修饰的成员内部类的所有成员方法对与内部类不同包的非子类是不可见的 --- 类不可见,其成员方法当然不可见;
4.Teacher 内的测试:
注意 28 行,提示的错误与其他行都不一样:
即,protected 修饰的成员内部类 InnerClassPro 的构造方法是不可见的.
但第 42 行,即 inCPro.printInCProPu(); 是没有问题的,也就是说 InnerClassPro 是可以在 Teacher 里使用的.
为什么会出现这样的矛盾呢?
分析:类 Teacher 与类 Person 不在同一个包里,但是其子类,所以 protected 修饰的内部类 InnerClassPro 对 Teacher 是可见的;但类 InnerClassPro 没有显式创建构造方法,所以其默认的构造方法也是 protected 的;对内部类 InnerClassPro 而言,类 Teacher 与其不在同一个包里,且不是其子类,所以,Teacher 是看不到 protected 修饰的构造方法的;
因此就出现了上面的错误.
对策:
为类 InnerClassPro 添加构造方法,并声明为 public 的,这样就能保证 Teacher 能看到其构造方法并正确的创建 InnerClassPro 的对象了.
代码如下:
修改后,就不会出现上面的问题了,见下图:
protected class InnerClassPro {
//构造方法为public
public InnerClassPro() {
}
...
}
Teacher 类里的完整测试代码如下,就不再一一分析了:
下图把 16 种情况的可见性依次列了出来,比较特殊的就是 protected 修饰的内部类 InnerClassPro 的 public 的成员方法,上面已详细解释说明过,不再赘述.(注:图有点大,可点开查看)
来源: https://www.cnblogs.com/chanchan/p/8281021.html