1.内部类通常用来解决“多重继承”的问题。 2.当希望隐藏一个类的实现,减少工程中.java文件数量,或者这个类不想被扩展时,你可以通过匿名内部类来创建一个类的对象。 3.java虽然无法直接在语法层面上支持闭包,但是可以通过内部类来模拟一个闭包的程序结构。
概念:在一个类的内部再定义一个完整的类。
语法:
1 2 3 4 class Outer { class Inner { } }
编译:Outer$Inner.class 和 Outer.class
特点:
编译之后可生成独立的字节码文件
内部类可直接访问外部类的私有成员,而不破坏封装
可为外部类提供必要的内部功能组件
1.1 成员内部类 概念:在类的内部定义,与实例变量、实例方法同级别的类。属于外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
语法:
1 2 3 4 5 Outer out = new Outer ();Inner in = out.new Inner (); Outer.this .属性名
特点:
当外部类、内部类存在重名属性时,会优先访问内部类属性。
成员内部类不能定义静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class TestMemberInnerClass { public static void main (String[] args) { Outer out = new Outer (); Outer.Inner in = out.new Inner (); out.m1(); in.m2(); } }class Outer { int a = 10 ; public Outer () { System.out.println("Outer()" ); } public void m1 () { System.out.println("Outer class m1()" ); } class Inner { int b = 20 ; int a = 30 ; public Inner () { System.out.println("Inner()" ); } public void m2 () { System.out.println("Inner class m2()" ); System.out.println("Outer a = " + Outer.this .a); System.out.println("Inner a = " + a); } } }
1.2 静态内部类 概念:不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
特点:
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class TestStaticInnerClass { public static void main (String[] args) { System.out.println(Outer.Inner.b); Outer.Inner in = new Outer .Inner(); in.m2(); } }class Outer { private static int a = 10 ; String s = "hello" ; static class Inner { static int b = 20 ; public void m2 () { System.out.println(Outer.a); System.out.println("Inner m2()" ); } } }
1.3 局部内部类 概念:定义在外部类的成员方法中,作用范围和创建对象范围仅限于当前方法
特点:
不能有静态成员(属性/方法)
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
隐藏类的信息,限制类的使用范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class TestLocalInnerClass { public static void main (String[] args) { Outer out = new Outer (); out.m1(); System.out.println(out.p); out.p.print(); } }interface Printable { public void print () ; }class Outer { int a = 10 ; Printable p = null ; public void m1 () { int b = 20 ; class Inner implements Printable { int c = 30 ; @Override public void print () { System.out.println(a); System.out.println(b); System.out.println(c); System.out.println("local inner m2()" ); } } Inner in = new Inner (); System.out.println(in.c); p = new Inner (); } }
示例:限制类的使用范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class TestLocalInnerClassForApply { public static void main (String[] args) { Teacher t = School.getTeacher(1 ); t.teach(); } }class School { public static Teacher getTeacher (int classNo) { class BeginnerTeacher extends Teacher { @Override public void teach () { System.out.println("初级老师在上课" ); } } class AdvancedTeacher extends Teacher { @Override public void teach () { System.out.println("高级老师在上课" ); } } Teacher currentTeacher = null ; if (classNo % 2 != 0 ) { currentTeacher = new BeginnerTeacher (); } else { currentTeacher = new AdvancedTeacher (); } return currentTeacher; } }abstract class Teacher { public abstract void teach () ; }
1.4 匿名内部类【实际编码中很常见】 概念:没有类名的局部内部类(一切特征都与局部内部类相同)
特点:
必须继承一个父类或者实现一个接口
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
使用场景:① 显式继承父类时 ② 实现接口时
优点:可以减少代码量,书写的思路流畅
缺点:可读性较差
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class TestAnonymiteInnerClass { public static void main (String[] args) { Teacher t = School.getTeacher(1 ); t.teach(); } }class School { public static Teacher getTeacher (int classNo) { Teacher currentTeacher = null ; if (classNo % 2 != 0 ) { currentTeacher = new Teacher () { @Override public void teach () { System.out.println("初级老师在上课" ); } }; } else { currentTeacher = new Teacher () { @Override public void teach () { System.out.println("高级老师在上课" ); } }; } return currentTeacher; } }abstract class Teacher { public abstract void teach () ; }