2020年9月3日 内部类总结
## 7.10 内部类 1、内部类的概念 声明在另外一个类里面的类就是内部类。 2、内部类的4种形式 (1)静态内部类 (2)非静态成员内部类 (3)有名字的局部内部类 (4)匿名内部类 ### 7.10.1 匿名内部类 1、语法格式: ```java //在匿名子类中调用父类的无参构造 new 父类(){ 内部类的成员列表 } //在匿名子类中调用父类的有参构造 new 父类(实参列表){ 内部类的成员列表 } //接口没有构造器,那么这里表示匿名子类调用自己的无参构造,调用默认父类Object的无参构造 new 父接口名(){ } ``` 2、匿名内部类、匿名对象的区别? ```java System.out.println(new Student("张三"));//匿名对象 Student stu = new Student("张三");//这个对象有名字,stu //既有匿名内部类,又是一个匿名的对象 new Object(){ public void test(){ ..... } }.test(); //这个匿名内部类的对象,使用obj这个名字引用它,既对象有名字,但是这个Object的子类没有名字 Object obj = new Object(){ public void test(){ ..... } }; ``` 3、使用的形式 (1)示例代码:继承式 ```java abstract class Father{ public abstract void test(); } class Test{ public static void main(String[] args){ //用父类与匿名内部类的对象构成多态引用 Father f = new Father(){ public void test(){ System.out.println("用匿名内部类继承了Father这个抽象类,重写了test抽象方法") } }; f.test(); } } ``` (2)示例代码:实现式 ```java interface Flyable{ void fly(); } class Test{ public static void main(String[] args){ //用父接口与匿名内部类的对象构成了多态引用 Flyable f = new Flyable(){ public void fly(){ System.out.println("用匿名内部类实现了Flyable这个接口,重写了抽象方法"); } }; f.fly(); } } ``` (3)示例代码:用匿名内部类的匿名对象直接调用方法 ```java new Object(){ public void test(){ System.out.println("用匿名内部类的匿名对象直接调用方法") } }.test(); ``` (4)示例代码:用匿名内部类的匿名对象直接作为实参 ```java Student[] all = new Student[3]; all[0] = new Student("张三",23); all[1] = new Student("李四",22); all[2] = new Student("王五",20); //用匿名内部类的匿名对象直接作为实参 //这个匿名内部类实现了Comparator接口 //这个匿名内部类的对象,是定制比较器的对象 Arrays.sort(all, new Comparator(){ public int compare(Obeject o1, Object o2){ Student s1 = (Student)o1; Student s2 = (Student)o2; return s1.getAge() - s2.getAge(); } }); ``` ### 7.10.2 静态内部类 1、语法格式 ```java 【修饰符】 class 外部类名 【extends 外部类的父类】 【implements 外部类的父接口们】{ 【其他修饰符】 static class 静态内部类 【extends 静态内部类自己的父类】 【implements 静态内部类的父接口们】{ 静态内部类的成员列表; } 外部类的其他成员列表; } ``` 2、 使用注意事项 (1)包含成员是否有要求: 可以包含类的所有成员 (2)修饰符要求: * 权限修饰符:4种 * 其他修饰符:abstract、final (3)使用外部类的成员上是否有要求 * 只能使用外部类的静态成员 (4)在外部类中使用静态内部类是否有要求 * 正常使用 (5)在外部类的外面使用静态内部类是否有要求 ```java (1)如果使用的是静态内部类的静态成员 外部类名.静态内部类名.静态成员 (2)如果使用的是静态内部类的非静态成员 ①先创建静态内部类的对象 外部类名.静态内部类名 对象名 = new 外部类名.静态内部类名(【实参列表】); ②通过对象调用非静态成员 对象名.xxx ``` (6)字节码文件形式:外部类名$静态内部类名.class 3、示例代码 ```java class Outer{ private static int i = 10; static class Inner{ public void method(){ //... System.out.println(i);//可以 } public static void test(){ //... System.out.println(i);//可以 } } public void outMethod(){ Inner in = new Inner(); in.method(); } public static void outTest(){ Inner in = new Inner(); in.method(); } } class Test{ public static void main(String[] args){ Outer.Inner.test(); Outer.Inner in = new Outer.Inner(); in.method(); } } ``` ### 7.10.3 非静态内部类 1、语法格式 ```java 【修饰符】 class 外部类名 【extends 外部类的父类】 【implements 外部类的父接口们】{ 【修饰符】 class 非静态内部类 【extends 非静态内部类自己的父类】 【implements 非静态内部类的父接口们】{ 非静态内部类的成员列表; } 外部类的其他成员列表; } ``` 2、 使用注意事项 (1)包含成员是否有要求: 不允许出现静态的成员 (2)修饰符要求 权限修饰符:4种 其他修饰符:abstract,final (3)使用外部类的成员上是否有要求 都可以使用 (4)在外部类中使用非静态内部类是否有要求 在外部类的静态成员中不能使用非静态内部类 (5)在外部类的外面使用非静态内部类是否有要求 ```java //使用非静态内部类的非静态成员 //(1)创建外部类的对象 外部类名 对象名1 = new 外部类名(【实参列表】); //(2)通过外部类的对象去创建或获取非静态内部类的对象 //创建 外部类名.非静态内部类名 对象名2 = 对象名1.new 非静态内部类名(【实参列表】); //获取 外部类名.非静态内部类名 对象名2 = 对象名1.get非静态内部类对象的方法(【实参列表】); //(3)通过非静态内部类调用它的非静态成员 对象名2.xxx ``` (6)字节码文件形式:外部类名$非静态内部类名.class 3、示例代码 ```java class Outer{ private static int i = 10; private int j = 20; class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//可以 } } public void outMethod(){ Inner in = new Inner(); in.method(); } public static void outTest(){ // Inner in = new Inner();//不可以 } public Inner getInner(){ return new Inner(); } } class Test{ public static void main(String[] args){ Outer out = new Outer(); Outer.Inner in1 = out.new Inner(); //创建 in1.method(); Outer.Inner in2 = out.getInner(); //获取 in2.method(); } } ``` ### 7.10.4 局部内部类 1、语法格式 ```java 【修饰符】 class 外部类名 【extends 外部类的父类】 【implements 外部类的父接口们】{ 【修饰符】 返回值类型 方法名(【形参列表】){ 【修饰符】 class 局部内部类 【extends 局部内部类自己的父类】 【implements 局部内部类的父接口们】{ 局部内部类的成员列表; } } 外部类的其他成员列表; } ``` 2、 使用注意事项 (1)包含成员是否有要求 不允许出现静态的成员 (2)修饰符要求 权限修饰符:不能 其他修饰符:abstract、final (3)使用外部类的成员等上是否有要求 ①使用外部类的静态成员:随便用 ②使用外部类的非静态成员:能不能用要看所在的方法是否是静态的 ③使用所在方法的局部变量:必须 final修饰的 (4)在外部类中使用局部内部类是否有要求 有作用域 (5)在外部类的外面使用局部内部类是否有要求 没法使用 (6)字节码文件形式:外部类名$编号局部内部类名.class 3、示例代码 ```java class Outer{ private static int i = 10; private int j = 20; public void outMethod(){ class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//可以 } } Inner in = new Inner(); in.method(); } public static void outTest(){ final int k = 30; class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//不可以 System.out.println(k);//可以 } } Inner in = new Inner(); in.method(); } }