什么是内部类

将一个类A定义在一个类B里面,类A就称为内部类,类B称为外部类

内部类的分类

  • 成员内部类
  • 局部内部类
  • 匿名内部类

成员内部类

描述事物时,一个事物内部还包含其他事物,可以使用内部类这种结构。

成员内部类格式

class 外部类 {
    class 内部类{ 
    }
}

成员内部类访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员。
  • 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象格式

外部类名.内部类名 对象名 = new 外部类型().new 内部类型();

代码演示

  • 定义类
public class Person {

    private boolean live;

    public void setLive(boolean live) {
        this.live = live;
    }
    //内部类
    class Heart{
        public void jump(){
            
            //内部类可以直接访问外部类的成员,包括私有
            if (live){
                System.out.println("跳动");
            }else{
                System.out.println("停止跳动");
            }
        }
    }
}
  • 测试类
public class InnerDemo {
    public static void main(String[] args) {       
        //创建外部类对象
        Person p = new Person();
        p.setLive(true);

        //创建内部类对象
        Person.Heart heart = p.new Heart();

        //调用内部类方法
        heart.jump();
    }
}

内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。比如,Person$Heart.class

局部内部类

什么是局部内部类

将一个类定义在一个方法中,该类就称之为是局部内部类

如何使用局部内部类

只能在该方法内部使用局部内部类

代码演示

public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.show();
    }
}

public class Outer {
    
    public void show(){
        // 局部内部类
        class Inner{
            public void method(){
                System.out.println("Inner 局部内部类的method方法执行了....");
            }
        }

        // 在外部类的方法内使用局部内部类
        Inner inner = new Inner();
        inner.method();
    }
}

匿名内部类

内部类的简化写法。本质是一个带具体实现的父类或者父接口的匿名的子类对象。 开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,

定义子类 实现接口
重写接口中的方法 
创建子类对象 
调用重写后的方法

使用匿名内部类的前提

匿名内部类必须==继承一个父类==或者==实现一个父接口==。

匿名内部类的格式

new 父类名或者接口名(){
    // 方法重写
    @Override 
    public void method() {       
        // 执行语句
    }
};

匿名内部类的使用

以接口为例,匿名内部类的使用,代码如下:

定义接口

public interface FlyAble{
    public abstract void fly();
}

方式一 创建匿名内部类,并调用

public class InnerDemo {
    public static void main(String[] args) {
        //直接new接口,无需写实现类来实现接口
        new FlyAble(){
           //直接实现方法
            public void fly() {
                System.out.println("飞~~~");
            }
        }.fly();
    }
}

方式二 常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:

public class InnerDemo2 {
    public static void main(String[] args) {
        FlyAble f = new FlyAble(){
            //直接重写抽象方法
            public void fly(){
                System.out.println("我要飞,飞啊,飞,01");
            }
            @Override
            public void fly2() {
                System.out.println("我要飞,飞啊,飞,02");
            }
        };
        f.fly();
        f.fly2();
    }
}

方式三 匿名内部类调用

public class InnerDemo3 {
    public static void main(String[] args) {
        showFly(new FlyAble() {
            @Override
            public void fly() {
                System.out.println("~~~~~~~~~~~~~~~");
            }
            @Override
            public void fly2() {
                System.out.println("----------------");
            }
        });
    }
    public static void showFly(FlyAble f){
        f.fly();
        f.fly2();
    }
}

匿名内部类好处:就是可以不用再写一个实现类来实现接口,可以直接使用