Java八股文系列五:内部类

362 阅读2分钟

image

一、什么是内部类

将一个类定义置入另一个类定义中,这个类就叫做内部类。简单来说就是在一个类的内部再定义一个类。

二、为什么要用内部类

  1. 内部类与外部类之间可以很方便地访问彼此的私有域。
  2. 内部类是另外的一种封装,对外部的其他类隐藏。
  3. 内部类可以打破Java单继承的局限。

缺点就是结构复杂。

如何使用内部类呢?

  • 在外部类外部生成非静态内部类实例
Outer.Inner in = new Outer().new Inner();
  • 在外部类外部生成静态内部实例
Outer.Inner in = new Outer.Inner();
  • 在外部类内部生成内部类实例
Inner in = new Inner();

三、内部类的分类

Java内部类主要分为四种:成员内部类、静态内部类、方法内部类、匿名内部类。

3.1 成员内部类

成员内部类是内部类中最普通的一种,对比成员方法:

public class Outer1 {
    private String name = "test";
    public static int age = 20;
    class Inner {
        public void getOuter() {
            System.out.println("name: " + name + " age: " + age);
        }
    }
    public static void main(String[] args) {
        Inner inner = new Outer1().new Inner();
        inner.getOuter();
    }
}

输出:

name: test age: 20
  1. ==成员内部类中不允许存在static域,正如成员方法中不允许存在static域。==
  2. ==成员内部类依附于外部类,只有创建了外部类实例才能创建内部类实例。==

3.2 静态内部类

static修饰的内部类称之为静态内部类。

public class Outer3 {
    public static String name = "张三";
    private int age = 20;
    static class Inner{
        private int num = 10;
        private static int height = 170;
        public void getOuter() {
            System.out.println("name: " + name + " num: " + num);
        }
    }

    public static void main(String[] args) {
        new Inner().getOuter();
        System.out.println(Inner.height);
    }
}

输出:

name: 张三 num: 10
170
  1. ==静态内部类的创建不需要依赖外部的类,可直接创建。==
  2. ==静态内部类不可以使用外部类的任何非static的域。==

3.3 局部内部类

局部内部类就是定义在方法里的类。

public class Outer2 {
    private int num = 10;
    public void getNum(final int tmp) {
        class Inner {
            public void test() {
                System.out.println(num);
                System.out.println(tmp);
            }
        }
        new Inner().test();
    }

    public static void main(String[] args) {
        new Outer2().getNum(20);
    }
}

输出:

10
20
  1. ==局部内部类不允许使用任何访问权限修饰符。==
  2. ==局部内部类对外部完全隐藏,只有定义了这个类的方法才可以访问。==
  3. ==局部内部类中的方法如果想使用定义它的方法的形参,则该参数必须使用final声明。==

3.4 匿名内部类

匿名内部类就是一个没有名字的局部内部类。

public interface MyInterface {
    void test();
}
public class Outer4 {
    private int age = 10;
    public MyInterface display(int tmp) {
        return new MyInterface() {
            @Override
            public void test() {
                System.out.println("age: " + age + " tmp: " + tmp);
            }
        };
    }
    public static void main(String[] args) {
        Outer4 outer4 = new Outer4();
        outer4.display(20).test();
    }
}

输出:

age: 10 tmp: 20
  1. 匿名内部类必须继承一个抽象类或者实现一个接口。
  2. 匿名内部类没有类名,因此没有构造方法。