内部类的好处:

  • 将类的代码隐藏在其他类内部。
  • 内部类对象可以访问外部类的所有元素
  • 解决多继承的问题。
  • 内部类可以有多个实例,与外部类独立。
  • 单个外部类可以让多个内部类实现同一个接口或继承同一个类。

    一、成员内部类:

    1. public class Outer{
    2. class Inner{
    3. }
    4. }

获取内部类对象实例的方式

  • 普通内部类对象隐式的保存了一个指向外部类对象的引用。
  • new 外部类 . new 内部类。
  • 外部类对象 . new 内部类。
  • 外部类对象 . get方法。

10.3 使用.this和.new

  • 内部类中获取外部类对象的引用:外部类.this 。
  • 外部类中访问内部类对象的引用:new 内部类()。
  • 外部类中创建内部类对象必须使用外部类对象来创建内部类对象。
    • image.png

      10.4 内部类和向上转型

      内部类也可以和普通类一样拥有向上转型的特性。将内部类向上转型为基类型,尤其是接口时,内部类就有了用武之地。如果内部类是private的,只可以被它的外部类问,从而完全隐藏实现的细节。

二、10.5 方法内部类

  • 方法中创建类。
  • 类前不能加访问说明符,类中不能有静态成员。
  • 可以访问代码块内的常量和外部类的所有成员。

    使用场景:

  • 实现了某接口,创建并返回对其的引用。

  • 需要创建一个类辅助解决问题,但不希望这个类公共可用。
    1. public Object getInner{
    2. class Inner{
    3. ...
    4. }
    5. }

三、10.6 匿名内部类

使用场景:

  • 只用到类的一个实例,因为不会有对象名称,无法再次调用。
  • 实例化的同时重写方法,等同于创建子类继承父类并重写方法或实现接口。
  • 没有静态成员
    1. test.getRead(new Person(){ //实例化的同时重写方法,等同于创建子类继承父类并重写方法。
    2. @Override
    3. public void read(){
    4. ...
    5. }
    6. })

四、10.7 静态内部类(嵌套类)

使用场景:

  • 不需要内部类对象与外部类有联系。

    与普通内部类的区别:

  • 普通内部类对象隐式的保存了一个指向外部类对象的引用,而静态内部类没有。

  • 静态内部类创建对象不需要外部类对象。
  • 普通内部类不能有static成员,而静态内部类可以。

    1. public class Outer{
    2. static class Inner{
    3. }
    4. }
  • 静态内部类中,不能通过对象访问非静态的外部类对象。

  • 创建静态内部类对象:外部类.内部类 类名 = new 外部类.内部类();

    10.7.1 接口内部可以放静态内部类

    正常情况接口内部不能放代码,但是静态内部类可以放,自动的public和static。
    1. public interface A{
    2. void fun();
    3. class Test implements A{
    4. public void fun(){
    5. ...
    6. }
    7. ...
    8. }
    9. }

10.9 内部类的继承

内部类对象隐式的包含对外部类对象的引用,所以在继承内部类的同时,构造器需要通过特殊语法初始化这个引用。

  • 外部类对象 . super() ```java class Outer{ class Inner{} }

public class A extends Outer,Inner{ // A(){}不能通过编译。 必须通过外部类对象.super初始化内部类对象对外部类对象的引用。 A(Outer o){ o.super(); } } ```