百知教育 - 孙帅 - 11_内部类
01_内部类概述
-
概念:
在一个类的内部再定义一个完整类 -
特点(编译时类型:运行时,用到哪个类就加载哪个类,不分内外):
- 编译之后分别生成独立的字节码文件。
- 内部类可直接访问外部类的私有成员,而不破坏封装。
- 可为外部类提供必要的内部功能组件。
-
分类:
成员内部类、静态内部类、局部内部类、匿名内部类 -
代码(编译通过):
package day13; public class TestInnerClass{ public static void main(String[] args){ } } class Outer{ private static int a = 10; public void m(){ int x = 20; class LocalInner{} } class MemberInner{ public void method(){ System.out.println(a); } } static class StaticInner{} }
02_成员内部类
-
创建对象:
先创建外部类对象,再通过“外部类对象.new 内部类类名()” 创建内部类对象。 -
引用外部类的当前对象语法:
外部类类名.this -
代码:
package day13; public class TestInnerClass{ public static void main(String[] args){ Outer o1 = new Outer(10); Outer o2 = new Outer(20); Outer.MemberInner in1 = o1.new MemberInner(); in1.method(); //Outer.MemberInner in2 = o2.new MemberInner(); //in2.method(); } } class Outer{ private int a = 10; public Outer(int a){ this.a = a; } public void m(){ int x = 20; class LocalInner{} } class MemberInner{ private int a = 30; public void method(){ int a = 40; System.out.println(a); System.out.println(this.a); System.out.println(Outer.this.a); } } static class StaticInner{} }
-
运行结果:
03_静态内部类
-
特点:
只能访问外部类的 静态成员
-
代码:
package day13; public class TestInnerClass{ public static void main(String[] args){ /* Outer o1 = new Outer(10); Outer o2 = new Outer(20); Outer.MemberInner in1 = o1.new MemberInner(); in1.method(); //Outer.MemberInner in2 = o2.new MemberInner(); //in2.method(); */ Outer.StaticInner in3 = new Outer.StaticInner(); in3.method(); } } class Outer{ private int a = 10; private static int b = 20; public Outer(int a){ this.a = a; } public void m(){ int x = 20; class LocalInner{} } class MemberInner{ private int a = 30; public void method(){ int a = 40; System.out.println(a); System.out.println(this.a); System.out.println(Outer.this.a); } } static class StaticInner{ private int x = 10; public void method(){ System.out.println(x); //System.out.println(a); //error! System.out.println(b); } } }
-
运行结果:
04_局部内部类
-
作用范围:
从定义开始,到代码块结束 -
特点:
- 局部内部类 不能定义静态成员
- 局部内部类可以访问外部类的私有成员,还能访问外部类的局部变量,但是要加final
-
代码:
package day13; public class TestTeacher{ public static void main(String[] args) { Student s = new Student(); s.study(); } } class School{ public static Teacher getTeacher(int n){ class TeacherA implements Teacher{ public void teach(){ System.out.println("TeacherA 讲课"); } } class TeacherB implements Teacher{ public void teach(){ System.out.println("TeacherB 讲课"); } } if(n % 2 == 0) return new TeacherA(); else return new TeacherB(); } } class Student{ public void study(){ Teacher t = School.getTeacher(1); t.teach(); } } interface Teacher{ void teach(); }
-
运行结果:
05_局部内部类访问外部类局部变量
-
虚拟机内存:
- 堆空间: 存放 对象
- 栈空间: 存放 局部变量
- 方法区: 存放 常量池、类的静态数据 等
-
反编译命令:
javap -verbose(为了看到类最全的信息) 类名(可查看) -
代码(编译通过):
package day13; public class TestLocalInnerClass{ public static void main(String[] args){ } } class A{ public void method(){ final int x = 10; final double y = Math.random(); class B{ public void print(){ System.out.println(x); System.out.println(y); } } B b = new B(); b.print(); } } /* class A{ private int m = 100; public void method(){ final int x = 10; final double y = Math.random(); class B{ A a; double y; public B(A a, double y){ this.a = a; this.y = y; } public void print(){ System.out.println(a.m); System.out.println(10); Ssytem.out.println(y); } } B b = new B(this, y); b.print(); } } */
06_匿名内部类(特殊的局部内部类)
-
特点:
- 继承某个类或者实现某个接口
- 只会创建一个对象
-
语法:
new 父类名或者接口名{继承父类或者实现接口的代码}
-
代码(编译通过):
package day13; public class TestAnonymousInnerClass{ public static void main(String[] args){ method(new InterfaceA(){ public void m1(){ } public void m2(){ } }, new InterfaceB(){ public void m3(){ } public void m4(){ } public void m5(){ } }); } static void method(InterfaceA a, InterfaceB b){ a.m1(); a.m2(); b.m3(); } } interface InterfaceA{ void m1(); void m2(); } interface InterfaceB{ void m3(); void m4(); void m5(); }