内部类(Inner Class)是Java中的一种特殊类。内部类可以看做是定义在另一个类内部的类,因此也称为嵌套类(Nested Class)。可以通过内部类实现一些特殊的功能,例如封装、回调等等。
内部类的访问特点:
其中静态内部类只能访问外部类静态的方法和属性。其余的内部类可以访问所有的外部类成员变量及方法。静态内部类不依赖于外部类存在。
其他内部类可以访问外部类是因为持有了外部类的引用。内部类对象依赖于外部类对象存在。创建内部类对象之前,必须先创建外部类对象实例。
反过来,外部类不能直接使用内部类的成员变量和方法。必须先创建内部类的对象再通过内部类对象访问其方法。
外部类要访问内部类成员,必须要创建对象。例如:
class Car{
String carName;
int CarAge;
int CarColor;
class Engine{
private int engineAge;
}
void test(){
Engine e = new Engine();
System.out.println(e.engineAge);
}
}
以下是一些内部类的使用场景:
-
当B类表示是A类的一部分,且B类单独存在没有意义。
-
内部类可以实现回调函数,例如将内部类的引用传给其他的对象,从而实现异步操作。
-
内部类可以提高代码的可读性和可维护性,例如在某个方法中使用一个匿名内部类,可以让代码更加简洁明了。
-
内部类的分类:
-
成员内部类:
写在成员位置的,属于外部类的成员。
成员内部类可以被一些修饰符所修饰,比如private,默认,protected,public,static(静态内部类)等
在JDK16之后可以定义静态变量。
如何创建内部类对象:
方式一:在外部类中编写方法,创建成员内部类对象。
Outer o = new Outer(); //直接用 System.out.println(o.getInstance()); //创对象 Outer.Inner oi = o.getInstance(); //当成员内部类被private修饰时,用多态 Object oi = o.getInstance();
-
方式二:外部类名.内部类名 对象名 = 外部类对象.内部类对象,例如
Outer.Inner oi = new Outer().new Inner();
关于成员调用:
class Car{ private int a = 10; class Engine{ private int a = 20; void test(){ int a = 30; System.out.println(Car.this.a); //10 System.out.println(this.a); //20 System.out.println(a); //30 } } }
Outer.this是值外部类地址。
-
静态内部类
静态内部类由static修饰符修饰。
调用:Outer.Inner.show() //直接调用,只能调静态 Outer.Inner oi = new Outer.Inner() //可调用非静态
-
局部内部类
将内部类定义在方法里的称为局部内部类。
外界是无法直接使用局部内部类,需要在方法内部创建对象并使用。
使用方法类似于局部变量。 -
匿名内部类
匿名内部类的本质就是隐藏了名字的内部类。
应用场景:
设计类的最终目的是为了创建一个类的实例,如果一个类的实例只使用一次,可以将类的定义和实例的创建一起完成,这种定义的没有名字的类称为匿名内部类。 -
格式:
new 继承的类名或实现的接口名(){ 重写方法; };
可以写在成员位置,也可以写在局部位置。
-
使用场景:
当方法的参数是接口或类时,如果实现类只使用一次,就可以用匿名内部类简化代码。