一.内部类
内部类 : 一个类定义在另一个类的内部 , 叫做内部类 .
内部类共有四种 :
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
1.成员内部类
在类的内部再定义一个类 , 是类中的一个普通成员 , 就像成员变量 , 成员方法一样 .
在JDK16之后 , 成员内部类中可以定义静态成员 . 在创建对象时 , 要先创建外部类的对象 , 再创建内部类的对象 , 例 : Outer.Inner in = new Outer().new Inner();
成员内部类既可以访问自己类中的成员 , 也可以访问外部类的成员 , 自己类中的直接使用或用this. 调用 , 外部类中的用 ( 外部类名 . this ) 调用 .
代码示例 :
public class Test01{ public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); // 创建成员内部类Inner对象 in.print(); // 用对象in调用Inner的方法print() } } class Outer{ // 定义外部类 private int age = 18; // 外部类的成员变量 age = 18 public class Inner{ // 定义成员内部类 private int age = 20; // 成员内部类的成员变量 age = 20 public void print(){ // 成员内部类的成员方法 print() int age = 22; // 方法里定义的成员变量 age = 22; System.out.println(age); // 22 就近原则,输出方法里的成员变量 System.out.println(this.age); // 20 this调用成员内部类的成员变量 System.out.println(Outer.this.age); // 18 用 外部类名.this. 调用外部类的成员变量 } } }
控制台输出 :
22 20 18
2.静态内部类
用static关键字修饰的内部类 , 是外部类独有的 , 可以直接用外部类的类名调用 , 不用新创建外部类的对象 , 例 : Outer.Inner in = new Outer.Inner();
静态内部类可以访问外部类的静态成员 , 不能访问实例成员 .
代码示例 :
public class Test01{ public static void main(String[] args) { Outer.Inner in = new Outer.Inner(); // 创建Inner对象,不用先创建Outer对象 in.print(); // 用对象in调用静态内部类的方法print() } } class Outer{ private int age = 18; private static int score = 99; // 静态的外部类成员变量 public static class Inner{ private int age = 19; private static int score = 95; // 静态的内部类成员变量 public void print(){ System.out.println(age); // 19 //System.out.println(Outer.this.age); // 报错 Outer的age不是静态的 System.out.println(score); // 95 System.out.println(Outer.score); // 99 //System.out.println(Outer.this.score); // 报错 静态方法/类里不能引用this关键字 } } }
控制台输出 :
19 95 99
3.局部内部类
局部内部类 , 它定义在外部类中的方法体中、代码块中、构造器等执行体中 . 一般情况下 , 它的应用很少 .
代码示例 :
public class Test01 { public static void main(String[] args) { outer(); Outer outer = new Outer(); { // 代码块 class Inner3 { // 代码块中的内部类,使用范围只能在代码块里 public void print3() { System.out.println("代码块中的局部内部类"); } } Inner3 inner3 = new Inner3(); // 创建Inner3对象 inner3.print3(); // 调用print3方法 } } public static void outer() { // 定义outer方法 class Inner2 { // 方法中的内部类,只能在方法里使用 public void print2() { System.out.println("方法体中的局部内部类"); } } Inner2 inner2 = new Inner2(); // 创建Inner2对象 inner2.print2(); // 调用print2方法 } } class Outer{ // 外部类 public Outer() { // 外部类的构造器 class Inner1{ // 构造器中的内部类 public void print1(){ System.out.println("构造器中的局部内部类"); } } Inner1 inner1 = new Inner1(); // 创建Inner1对象 inner1.print1(); // 调用print1对象 } }
控制台输出 :
方法体中的局部内部类 构造器中的局部内部类 代码块中的局部内部类
4.匿名内部类
为了更方便地创建子类对象 , 匿名内部类产生了 . 它不用为类声明名字 , 但可以立即创建一个子类对象 , 是一种特殊的局部内部类 , 是最重要也是最常用的一种 . 匿名内部类通常作为一个参数传输给方法 . 它的格式为 :
new 类或接口(参数值...) {
类体 ( 一般是方法重写 )
};
示例 :
new Person(){ @Override public void work(){ //重写的方法体 } };
代码示例 :
public class Test02 { public static void main(String[] args) { print1(new Person() { // 匿名内部类作为参数传进print1方法里 @Override public void work1() { // 重写work1方法 System.out.println("人们在工作"); } }); print2(new Cook() { // 匿名内部类作为参数传进print2方法里 @Override void work2() { // 重写work2方法 System.out.println("厨师在做饭"); } }); } private static void print2(Cook c) { c.work2(); // 调用重写的work2方法 } private static void print1(Person p) { p.work1(); // 调用重写的work1方法 } } interface Person{ // 接口 void work1(); } abstract class Cook{ // 抽象类 abstract void work2(); }
控制台输出 :
人们在工作 厨师在做饭