1. 内部类
概念:在一个类的内部再定义一个完整的类
class OuterClass {
...
class InnerClass {
...
}
}
要实例化内部类InnerClass,必须先实例化外部类OuterClass
1.1 特点
-
- 编译之后可生成独立的字节码文件
- 外部类与内部类之间使用
$符号分隔,示例Outer.class, Outer$Inner.class - 匿名内部类使用
数字进行编号,示例Outer.class, Outer$1.class
-
- 内部类可直接访问外部类的私有成员,而不破坏封装
- 内部类通过 this 访问外部类的成员
- 可为外部类提供必要的内部功能组件
1.2 作用
- 1.可以无条件地访问外部类的所有元素
- 2.实现隐藏:内部类比外部类可以多使用private、protected 修饰符
- 3.可以实现多重继承(多个内部类分别继承别的类)
- 4.通过匿名内部类来优化简单的接口实现
2. 成员内部类
- 成员内部类与实例变量、实例方法同级别
- 成员内部类是依附外部类而存在的,创建成员内部类对象时,必须依赖外部类对象
- 当外部类与内部类的属性重名时,优先访问内部类属性
- 成员内部类不能定义静态成员,但可以包含静态常量 final
public class Outer {
private String name = "Bob";
// 默认作用域:包内可见
public class Inner {
private String name = "Alice";
// 4. 静态常量 final
private static final String address = "...";
public void show() {
System.out.println(name); // 等价 this.name
// 3. 属性相同时,外部类使用 Outer.this
System.out.println(Outer.this.name);
}
}
}
实例化成员内部类
@Test
public void test() {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// or
Outer.Inner inner = new Outer().new Inner();
}
2.1 接口中的成员内部类
@Test
public void test() {
OuterInterface.Inner inner = new OuterInterface.Inner();
inner.show();
}
public interface OuterInterface {
class Inner {
// 可以有静态属性
private static String address = "";
public void show() {
}
}
}
3. 局部内部类
- 定义在外部类方法中
- 作用范围和创建对象的范围仅限于当前方法
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,所以该局部变量必须修饰为 final
- 局部内部类也不能定义静态成员,但可以包含静态常量 final
public class Outer {
private String name = "Bob";
public void show() {
String address = "...";
// 局部内部类在 方法 里声明
class Inner {
private Integer age;
public void innerShow() {
System.out.println(Outer.this.name);
// 局部内部类里访问局部变量,JDK1.7 要求变量必须是常量final,JDK1.8 自动添加final
System.out.println(address);
// Variable 'address' is accessed from within inner class, needs to be final or effectively final
// address = "111";
}
}
Inner inner = new Inner();
inner.innerShow();
}
}
访问测试
@Test
public void test() {
Outer outer = new Outer();
outer.show();
}
3.1 address 为什么是 final
address 若是一个普通属性,当 show() 方法执行完之后,局部变量 address 就会消失
show() 里面的 Inner inner = new Inner(); new Inner() 在堆里,不会立即消失,innerShow() 属于类 Inner 也不会立即消失
变量 address 没有了但类还在,不合理,所以是 final 类型
4. 匿名内部类
见文章 https://www.jianshu.com/p/463a7ae13fc5
5. 扩展
5.1 内部类实现接口
public class OuterClass {
public OutInterface newInnerClass() {
return new InnerClass();
}
private class InnerClass implements OutInterface {
@Override
public void out() {
System.out.println("InnerClass execute");
}
}
}
public interface OutInterface {
void out();
}
访问测试
@Test
public void test() {
OuterClass out = new OuterClass();
OutInterface outInterface = out.newInnerClass();
outInterface.out();
}







网友评论