内部类的好处:
- 将类的代码隐藏在其他类内部。
- 内部类对象可以访问外部类的所有元素 。
- 解决多继承的问题。
- 内部类可以有多个实例,与外部类独立。
- 单个外部类可以让多个内部类实现同一个接口或继承同一个类。
一、成员内部类:
1 | public class Outer{ |
获取内部类对象实例的方式
- 普通内部类对象隐式的保存了一个指向外部类对象的引用。
- new 外部类 . new 内部类。
- 外部类对象 . new 内部类。
- 外部类对象 . get方法。
10.3 使用.this和.new
- 内部类中获取外部类对象的引用:外部类.this 。
- 外部类中访问内部类对象的引用:new 内部类()。
- 外部类中创建内部类对象必须使用外部类对象来创建内部类对象。
10.4 内部类和向上转型
内部类也可以和普通类一样拥有向上转型的特性。将内部类向上转型为基类型,尤其是接口时,内部类就有了用武之地。如果内部类是private的,只可以被它的外部类问,从而完全隐藏实现的细节。
二、10.5 方法内部类
- 方法中创建类。
- 类前不能加访问说明符,类中不能有静态成员。
- 可以访问代码块内的常量和外部类的所有成员。
使用场景:
- 实现了某接口,创建并返回对其的引用。
- 需要创建一个类辅助解决问题,但不希望这个类公共可用。
1
2
3
4
5public Object getInner{
class Inner{
...
}
}
三、10.6 匿名内部类
使用场景:
- 只用到类的一个实例,因为不会有对象名称,无法再次调用。
- 实例化的同时重写方法,等同于创建子类继承父类并重写方法或实现接口。
- 没有静态成员
1
2
3
4
5
6test.getRead(new Person(){ //实例化的同时重写方法,等同于创建子类继承父类并重写方法。
public void read(){
...
}
})
四、10.7 静态内部类(嵌套类)
使用场景:
- 不需要内部类对象与外部类有联系。
与普通内部类的区别:
普通内部类对象隐式的保存了一个指向外部类对象的引用,而静态内部类没有。
静态内部类创建对象不需要外部类对象。
普通内部类不能有static成员,而静态内部类可以。
1
2
3
4public class Outer{
static class Inner{
}
}静态内部类中,不能通过对象访问非静态的外部类对象。
创建静态内部类对象:外部类.内部类 类名 = new 外部类.内部类();
10.7.1 接口内部可以放静态内部类
正常情况接口内部不能放代码,但是静态内部类可以放,自动的public和static。
1 | public interface A{ |
10.9 内部类的继承
内部类对象隐式的包含对外部类对象的引用,所以在继承内部类的同时,构造器需要通过特殊语法初始化这个引用。
- 外部类对象 . super()
1
2
3
4
5
6
7
8
9
10class Outer{
class Inner{}
}
public class A extends Outer,Inner{
// A(){}不能通过编译。 必须通过外部类对象.super初始化内部类对象对外部类对象的引用。
A(Outer o){
o.super();
}
}