一、什么是内部类
将一个类定义置入另一个类定义中,这个类就叫做内部类。简单来说就是在一个类的内部再定义一个类。
二、为什么要用内部类
- 内部类与外部类之间可以很方便地访问彼此的私有域。
- 内部类是另外的一种封装,对外部的其他类隐藏。
- 内部类可以打破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
- ==成员内部类中不允许存在static域,正如成员方法中不允许存在static域。==
- ==成员内部类依附于外部类,只有创建了外部类实例才能创建内部类实例。==
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
- ==静态内部类的创建不需要依赖外部的类,可直接创建。==
- ==静态内部类不可以使用外部类的任何非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
- ==局部内部类不允许使用任何访问权限修饰符。==
- ==局部内部类对外部完全隐藏,只有定义了这个类的方法才可以访问。==
- ==局部内部类中的方法如果想使用定义它的方法的形参,则该参数必须使用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
- 匿名内部类必须继承一个抽象类或者实现一个接口。
- 匿名内部类没有类名,因此没有构造方法。