#37.Inner Class.md
##37.1 四种内部类
在Java中,共有四种类型的内部列类,分别是:
- 静态内部类
- 内部类
- 本地内部类
- 匿名内部类
##37.2 静态内部类(或者接口)
在类(或者接口)内部以声明类成员的方法声明的类被称为静态内部类(接口)。由于外部和内部可以是类或者接口,因此,会有以下四种情况:
class Outer { // 外部是类,内部是类
static class Inner {}
}interface Outer { // 外部是接口,内部是类
static class Inner {}
}class Outer { // 外部是类,内部是接口
static interface Inner {}
}interface Outer { // 外部是接口,内部是接口
static interface Inner {}
}由于接口中的成员隐含地使用了static关键字修饰,因此当外部是接口时,静态内部类(接口)的static关键字可以不用显式声明。
主要注意的点:
- Java中,除了静态内部类(接口)以外的类或者接口都不能使用static修饰。C#中的类可以用static修饰,static修饰的类不能被实例化;
- 静态内部类与普通的类唯一的区别就只在于:静态内部类嵌套在其他的类内部;
- 静态内部类可以访问外部类的私有类变量或类方法;
- 外部类可以访问内部类的私有成员变量或方法, 当然,必须在持有静态内部类实例的前提下;
##37.3 内部类
在类内部以声明实例成员的方法声明的类(接口)被称为(非静态内部类(接口))。由于接口中的方法会隐含static的修饰,所以不存在接口非静态内部类(接口)(Inner non-statc Class or Interface)。
需要注意的点:
- 内部类的实例化需要依赖外部类,也就是说,要new一个内部类,需要要持有外部类实例;
- 内部类会隐含持有外部类实例的引用,当内部类存在时,对应的外部类不会被GC掉;
- 内部类实例存在,则一定会有对应的外部类实例,反过来则不通;
- 内部类可以访问外部类的私有成员变量和方法;
- 外部类可以访问内部类的私有成员变量和方法,前提是必须持有内部类的相关实例;、
- 内部类不能声明静态变量或静态方法;
##37.4 局部内部类
在代码块(例如方法、构造方法内部等)内部声明的类被称为局部内部类。
例如:
class SomeClass {
void someFunction() {
class Local {
}
}
}需要注意的点:
- 局部内部类仅限于声明它的方法块的内部使用;
- 局部内部类可以继承其他类或者实现其他接口;
- 局部内部类可以访问所在方法块里的所有变量,访问的变量必须使用final声明;
##37.5 匿名内部类
与局部内部类不同的时,匿名内部类没有类名,由于没有类型,匿名内部类不能声明自己的构造函数。
class SomeClass {
void someFunction() {
new Object() { };
}
}需要注意的点:
- 使用匿名内部类时,不能显式使用继承和实现接口,实际上匿名内部类已经隐含了这层关系;
- 匿名内部类可以访问所在方法块里的所有变量,访问的变量必须使用final声明;
- 局部内部类可以访问所在方法块里的所有变量,访问的变量必须使用final声明;
##37.6 Why Final
