一、什么是内部类
- 使用场景:
- 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类
- 概念:
- 可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
- 注意点:
- 内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件(外部类$内部类)
1.1 实例内部类
❤️实例内部类的定义:定义在类的内部,方法的外部,未被修饰的类
❤️实例内部类的使用:
class OuterClass{
public int a = 1;
public static int b = 2;
public static int c = 0;
class InnerClass{
int c = 3; //在实例内部类当中,不能定义静态成员变量
//public static int d = 4; 会报错,因为内部类的使用需要依赖对象
public static final int e = 5; //不会报错
//原理:final修饰表示这个是个常量,常量e在编译时就知道是个确定的值5,如果是static修饰的,要到运行的时候,才知道值是多少
public void state(){
System.out.println("这是实例内部类");
System.out.println(a);
System.out.println(b);
System.out.println(c); //优先访问这个类中自己的成员
System.out.println(OuterClass.this.c); //打印外部类中的同名变量
//结论:实例内部类,是存在于外部类的this中的
//System.out.println(d); 无法正常打印
System.out.println(e);
}
}
}
public class Main {
public static void main(String[] args) {
OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass2 = outerClass.new InnerClass();
innerClass2.state();
//innerClass.state(); 两者的效果一样
}
}
1.2 静态内部类
❤️为什么会有静态内部类 ------------> 实例内部类的创建还需要把外部类先创建下来,很麻烦,静态类不需要外部类的对象,就能实例化
❤️静态内部类的使用:
class OuterClass{
public int date1 = 1;
public static int date2 = 2;
static class InnerClass{
public int date3 = 3;
public static int date4 = 4;
public void state(){
//System.out.println(date1); 会报错,静态内部类当中无法访问外部的非静态成员
//如何访问静态内部类当中,如何访问外部的非静态成员
OuterClass outerClass = new OuterClass();
System.out.println(outerClass.date1);
System.out.println(date2);
System.out.println(date3);
System.out.println(date4);
}
}
}
public class Main{
public static void main(String[] args) {
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
innerClass.state(); //OuterClass.InnerClass是一个整体
}
}
1.3 局部内部类
❤️局部内部类的定义:
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,不能被public、static等修饰符修饰,一般使用的非常少
❤️局部内部类的使用:
class OuterClass {
public void test() {
class Inner {
public int data1 = 10;
}
Inner inner = new Inner(); //只能在其定义的位置使用
System.out.println(inner.data1);
}
}
1.4 匿名内部类
class Student implements Comparable<Student>{
@Override
public int compareTo(Student o) {
return 0;
}
}
interface Shape {
void draw();
}
public class Main {
public static void main(String[] args) {
Comparable<Student> comparable = new Student();
new Comparable<Student>(){ //创建了一个类,这个类实现了Comparable<Student>接口
@Override //又重写了compareTo方法,但是不知道这个对象名/类名是谁
public int compareTo(Student o) {
return 0;
}
};
int a = 10;
new Shape() { //创建了一个类,这个类实现了shape接口
@Override
public void draw() {
//a = 99; 在匿名内部类当中,访问的变量是不可以改变的
System.out.println("矩形!" + a);
}
}.draw(); //调用方法
}
}