前言:
将一个类定义在另一个类里面或者一个方法中,该类称之为内部类
一、作用:
- 提供更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类,如A类只能在B类中使用。
- 内部类成员可以直接访问外部类的私有数据,但是外部类不能访问内部类的实现细节,比如内部类的成员变量。
- 匿名内部类适用于创建那些仅需要一次使用的类。
二、四种修饰符的访问权限:
权限 | 类内 | 同包 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
default | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
内部类和外部类的访问权限就不一样,内部类的可以多用三个修饰符private,protected,static。
解释: 外部类的上一级是包,只有两个作用域:同一个包和任何位置。故对应的省略访问控制,public访问控制,内部类上一级是外部类,那么就具有4个作用域。
三、关系图:
四、非静态内部类:
- 内部类中不能拥有任何static的变量和方法。
- 其创建依赖于外部类,故只有先创建了外部类才能创建内部类。
- 非静态内部类的成员可以访问外部类的private成员,但反过来就不成立了。
- 外部类不能直接访问非静态内部类的实例变量,如果访问,则必须显示创建内部类对象。
- 其内部的方法中访问某个变量,顺序是方法的局部变量,内部类的成员变量,外部类的成员变量。调用方法是this、外部类名.this来依次调用
一般的,使用getxxx方法来获取非静态内部类,尤其是其内部类的构造函数无参时。
public class OuterClass { private String str; public void outerDisplay(){ System.out.println("outerClass..."); } public class InnerClass{ public void innerDisplay(){ //使用外围类的属性 str = "chenssy..."; System.out.println(str); //使用外围类的方法 outerDisplay(); } } /*推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 */ public InnerClass getInnerClass(){ return new InnerClass(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.getInnerClass(); inner.innerDisplay(); } } -------------------- chenssy... outerClass...
五、静态内部类:
- 它的创建是不需要依赖外部类的。
- 它不能使用任何外部类的非static成员变量和方法。
- 属于外部类本身,而不是属于外部类的某个对象。
- 无法访问外部类的实例变量,只能访问外部类的类成员
- 内部的实例方法也不能访问外部类的实例属性
- 外部类不能直接访问其成员,要通过其类名来访问
public class OuterClass { private String sex; public static String name = "chenssy"; static class InnerClass1{ /* 在静态内部类中可以存在静态成员 */ public static String _name1 = "chenssy_static"; public void display(){ /* * 静态内部类只能访问外围类的静态成员变量和方法 * 不能访问外围类的非静态成员变量和方法 */ System.out.println("OutClass name :" + name); } } class InnerClass2{ /* 非静态内部类中不能存在静态成员 */ public String _name2 = "chenssy_inner"; /* 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的 */ public void display(){ System.out.println("OuterClass name:" + name); } } //实例方法 public void display(){ /* 外围类访问静态内部类:内部类. */ System.out.println(InnerClass1._name1); /* 静态内部类 可以直接创建实例不需要依赖于外围类 */ new InnerClass1().display(); /* 非静态内部的创建需要依赖于外围类 */ OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2(); /* 方位非静态内部类的成员需要使用非静态内部类的实例 */ System.out.println(inner2._name2); inner2.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.display(); } }
六、局部内部类(用的很少,几乎没用过):
其作用域是所在方法,所以其他方法永远访问不到该方法的成员变量,故都不能使用访问控制修饰符