【原】Java学习笔记025 - 内部类
1 package cn.temptation; 2 3 public class Sample01 { 4 public static void main(String[] args) { 5 // 内部类(嵌套类):把类定义在其他类的内部,这个类被称为内部类(嵌套类) 6 7 // 内部类的分类:(根据所在位置及形式的不同) 8 // 1、成员内部类 9 // 2、静态内部类 10 // 3、局部内部类 11 // 4、匿名内部类 12 13 // 1、成员内部类:联想到成员变量和成员方法,内部类所在位置和类的成员同级 14 15 // 观察一下生成的字节码文件,有三个:Sample01.class、OuterClass01.class、OuterClass01$InnerClass01.class 16 // 成员内部类字节码名称为 外部类名称$成员内部类名称.class 17 18 // 创建成员内部类对象的方式1:通过调用成员内部类的构造函数 19 // 格式:外部类名.内部类名 成员内部类对象名 = 外部类对象. new 内部类构造函数(); 20 // 写法1 21 // OuterClass01.InnerClass01 innerClass01 = (new OuterClass01()).new InnerClass01(); 22 // 写法2 23 // OuterClass01.InnerClass01 innerClass01 = new OuterClass01().new InnerClass01(); 24 // System.out.println(innerClass01); // cn.temptation.OuterClass01$InnerClass01@15db9742 25 26 // 创建出外部类对象 27 OuterClass01 outerClass01 = new OuterClass01(); 28 OuterClass01.InnerClass01 innerClass01 = outerClass01.new InnerClass01(); 29 System.out.println(innerClass01); // cn.temptation.OuterClass01$InnerClass01@15db9742 30 } 31 } 32 33 // 外部类 34 class OuterClass01 { 35 // 成员内部类 36 class InnerClass01 { 37 38 } 39 }
1 package cn.temptation; 2 3 public class Sample02 { 4 public static void main(String[] args) { 5 // 创建成员内部类对象的方式2:通过调用成员内部类所在的外部类的成员方法,在外部类中创建出成员内部类的对象 6 OuterClass02 outerClass02 = new OuterClass02(); 7 8 // 创建多个成员内部类对象的写法 9 // OuterClass02.InnerClass02 inner1 = outerClass02.getInnerClass02(); 10 // System.out.println(inner1); // cn.temptation.OuterClass02$InnerClass02@15db9742 11 // OuterClass02.InnerClass02 inner2 = outerClass02.getInnerClass02(); 12 // System.out.println(inner2); // cn.temptation.OuterClass02$InnerClass02@6d06d69c 13 14 // 创建单个成员内部类对象的写法(使用单例模式的懒汉式) 15 OuterClass02.InnerClass02 inner3 = outerClass02.getInstance(); 16 System.out.println(inner3); // cn.temptation.OuterClass02$InnerClass02@15db9742 17 OuterClass02.InnerClass02 inner4 = outerClass02.getInstance(); 18 System.out.println(inner4); // cn.temptation.OuterClass02$InnerClass02@15db9742 19 20 // 此时,只能通过getInstance()方法获取InnerClass02内部类的对象 21 // 语法错误:The constructor OuterClass02.InnerClass02() is not visible 22 // OuterClass02.InnerClass02 test = new OuterClass02().new InnerClass02(); 23 } 24 } 25 26 // 外部类 27 class OuterClass02 { 28 // 成员变量 29 private InnerClass02 innerClass02; 30 31 // 成员方法 32 // 多例创建方法 33 public InnerClass02 getInnerClass02() { 34 return new InnerClass02(); 35 } 36 37 // 单例模式创建方法 38 public InnerClass02 getInstance() { 39 if (innerClass02 == null) { 40 innerClass02 = new InnerClass02(); 41 } 42 43 return innerClass02; 44 } 45 46 // 成员内部类 47 class InnerClass02 { 48 // 设置构造函数为私有 49 private InnerClass02() { 50 51 } 52 } 53 }
1 package cn.temptation; 2 3 public class Sample03 { 4 public static void main(String[] args) { 5 // 可以在调用时设置对成员内部类的访问规则 6 // 1、使用private修饰成员内部类,这样外部访问就无法访问成员内部类,只有通过外部类的成员方法 7 // 2、访问规则写在成员方法中 8 9 OuterClass03 outerClass03 = new OuterClass03(); 10 Object obj1 = outerClass03.getInnerClass03("admin"); 11 System.out.println(obj1); // cn.temptation.OuterClass03$InnerClass03@15db9742 12 13 Object obj2 = outerClass03.getInnerClass03("test"); 14 System.out.println(obj2); // null 15 } 16 } 17 18 // 外部类 19 class OuterClass03 { 20 // 成员变量 21 private InnerClass03 innerClass03; 22 23 // 成员方法 24 public Object getInnerClass03(String role) { 25 if ("admin".equals(role)) { 26 return getInstance(); 27 } else { 28 return null; 29 } 30 } 31 32 // 单例模式创建方法 33 private InnerClass03 getInstance() { 34 if (innerClass03 == null) { 35 innerClass03 = new InnerClass03(); 36 } 37 38 return innerClass03; 39 } 40 41 // 成员内部类 42 private class InnerClass03 { 43 44 } 45 }
1 package cn.temptation; 2 3 public class Sample04 { 4 public static void main(String[] args) { 5 // 成员内部类的特点: 6 // 1、成员内部类中可以直接访问所在的外部类的成员 7 // 2、成员内部类中可以直接访问所在的外部类的非静态的成员变量 和 静态的成员变量 8 } 9 } 10 11 // 外部类 12 class OuterClass04 { 13 // 非静态的成员变量 14 public int i = 2; 15 private int j = 3; 16 // 静态的成员变量 17 public static int x = 4; 18 private static int y = 5; 19 20 // 成员内部类 21 class InnerClass04 { 22 // 成员方法 23 public void showByInner() { 24 // 成员内部类对于所在的外部类的成员变量均可以访问(不论是用public修饰的,还是用private修饰的) 25 System.out.println(i); 26 System.out.println(j); 27 // 成员内部类对于所在的外部类的静态成员变量均可以访问(不论是用public修饰的,还是用private修饰的) 28 System.out.println(x); 29 System.out.println(y); 30 } 31 } 32 }
1 package cn.temptation; 2 3 public class Sample05 { 4 public static void main(String[] args) { 5 OuterClass05.InnerClass05 innerClass05 = new OuterClass05().new InnerClass05(); 6 innerClass05.showByInner(); 7 } 8 } 9 10 // 外部类 11 class OuterClass05 { 12 // 成员变量 13 public int i = 2; 14 public int k = 4; // 外部类的成员变量 和 内部类的成员变量同名 15 16 // 成员内部类 17 class InnerClass05 { 18 // 成员变量 19 public int j = 3; 20 public int k = 5; // 外部类的成员变量 和 内部类的成员变量同名 21 22 // 成员方法 23 public void showByInner() { 24 System.out.println(i); // 2 25 System.out.println(j); // 3 26 System.out.println(k); // 5 --- 内部类的成员变量(就近原则) 27 System.out.println(this.k); // 5 --- 内部类的成员变量(this指的是当前这个成员内部类对象) 28 29 System.out.println(OuterClass05.this.k); // 4 --- 外部类的成员变量,通过eclipse的识别 30 System.out.println(new OuterClass05()); // 外部类对象:cn.temptation.OuterClass05@15db9742 31 System.out.println((new OuterClass05()).k); // 4 --- 外部类的成员变量,通过创建外部类的对象 32 System.out.println(OuterClass05.this); // 外部类对象:cn.temptation.OuterClass05@6d06d69c 33 } 34 } 35 }
1 package cn.temptation; 2 3 public class Sample06 { 4 public static void main(String[] args) { 5 OuterClass06.InnerClass06 innerClass06 = new OuterClass06().new InnerClass06(); 6 innerClass06.showByInner(); 7 } 8 } 9 10 // 外部类 11 class OuterClass06 { 12 // 成员方法 13 public void method1() { 14 System.out.println("外部类的公有非静态成员方法"); 15 } 16 17 private void method2() { 18 System.out.println("外部类的私有非静态成员方法"); 19 } 20 21 public static void method3() { 22 System.out.println("外部类的公有静态成员方法"); 23 } 24 25 private static void method4() { 26 System.out.println("外部类的私有静态成员方法"); 27 } 28 29 // 成员内部类 30 class InnerClass06 { 31 // 成员方法 32 public void showByInner() { 33 // 成员内部类的成员方法可以访问外部类的所有成员方法(不论是否公有私有、不论是否静态非静态) 34 method1(); 35 method2(); 36 method3(); 37 method4(); 38 } 39 } 40 }
1 package cn.temptation; 2 3 public class Sample07 { 4 public static void main(String[] args) { 5 // 成员内部类有构造函数,并且创建时可以选择相应的构造函数重载方法 6 7 OuterClass07.InnerClass07 inner1 = new OuterClass07().new InnerClass07(); 8 System.out.println(inner1); 9 10 OuterClass07.InnerClass07 inner2 = new OuterClass07().new InnerClass07("param"); 11 System.out.println(inner2); 12 } 13 } 14 15 // 外部类 16 class OuterClass07 { 17 // 成员内部类 18 class InnerClass07 { 19 // 构造函数 20 public InnerClass07() { 21 System.out.println("这是内部类的无参构造函数"); 22 } 23 24 public InnerClass07(String str) { 25 System.out.println("这是内部类的有参构造函数,参数为:" + str); 26 } 27 } 28 }
1 package cn.temptation; 2 3 public class Sample08 { 4 public static void main(String[] args) { 5 // 2、静态内部类:联想到静态成员,使用static修饰 6 7 // 观察一下生成的字节码文件,有三个:Sample08.class、OuterClass08.class、OuterClass08$InnerClass08.class 8 // 静态内部类字节码名称为 外部类名称$静态内部类名称.class 9 10 // 创建静态内部类对象 11 // 格式:外部类名.内部类名 成员内部类对象名 = new 外部类名.内部类构造函数(); 12 13 // 语法错误:Illegal enclosing instance specification for type OuterClass08.InnerClass08 14 // OuterClass08.InnerClass08 innerClass08 = new OuterClass08().new InnerClass08(); 15 16 OuterClass08.InnerClass08 innerClass08 = new OuterClass08.InnerClass08(); 17 System.out.println(innerClass08); // cn.temptation.OuterClass08$InnerClass08@15db9742 18 } 19 } 20 21 // 外部类 22 class OuterClass08 { 23 // 静态内部类 24 static class InnerClass08 { 25 26 } 27 }
1 package cn.temptation; 2 3 public class Sample09 { 4 public static void main(String[] args) { 5 // 静态内部类的特点: 6 // 静态内部类中不论静态的成员方法还是非静态的成员方法只能访问所在的外部类的静态成员变量 7 } 8 } 9 // 外部类 10 class OuterClass09 { 11 // 非静态成员变量 12 public int i = 2; 13 private int j = 3; 14 // 静态成员变量 15 public static int x = 4; 16 private static int y = 5; 17 18 // 静态内部类 19 static class InnerClass09 { 20 // 非静态的成员方法 21 public void showByInner() { 22 // 静态内部类对外部类的非静态成员变量无法访问 23 // Cannot make a static reference to the non-static field i 24 // System.out.println(i); 25 // Cannot make a static reference to the non-static field j 26 // System.out.println(j); 27 28 // 静态内部类对外部类的静态成员变量可以访问 29 System.out.println(x); 30 System.out.println(y); 31 } 32 33 // 静态的成员方法 34 public static void showByInnerStatic() { 35 // 静态内部类对外部类的非静态成员变量无法访问 36 // Cannot make a static reference to the non-static field i 37 // System.out.println(i); 38 // Cannot make a static reference to the non-static field j 39 // System.out.println(j); 40 41 // 静态内部类对外部类的静态成员变量可以访问 42 System.out.println(x); 43 System.out.println(y); 44 } 45 } 46 }
1 package cn.temptation; 2 3 public class Sample10 { 4 public static void main(String[] args) { 5 // 静态内部类的特点: 6 // 静态内部类中不论静态的成员方法还是非静态的成员方法只能访问所在的外部类的静态成员方法 7 } 8 } 9 10 // 外部类 11 class OuterClass10 { 12 // 成员方法 13 public void method1() { 14 System.out.println("外部类的公有非静态成员方法"); 15 } 16 17 private void method2() { 18 System.out.println("外部类的私有非静态成员方法"); 19 } 20 21 public static void method3() { 22 System.out.println("外部类的公有静态成员方法"); 23 } 24 25 private static void method4() { 26 System.out.println("外部类的私有静态成员方法"); 27 } 28 29 // 成员内部类 30 static class InnerClass10 { 31 // 非静态成员方法 32 public void showByInner() { 33 // 静态内部类对外部类的非静态成员方法无法访问 34 // 语法错误:Cannot make a static reference to the non-static method method1() from the type OuterClass10 35 // method1(); 36 // 语法错误:Cannot make a static reference to the non-static method method2() from the type OuterClass10 37 // method2(); 38 39 // 静态内部类对外部类的静态成员方法可以访问 40 method3(); 41 method4(); 42 } 43 44 // 非静态成员方法 45 public void showByInnerStatic() { 46 // 静态内部类对外部类的非静态成员方法无法访问 47 // 语法错误:Cannot make a static reference to the non-static method method1() from the type OuterClass10 48 // method1(); 49 // 语法错误:Cannot make a static reference to the non-static method method2() from the type OuterClass10 50 // method2(); 51 52 // 静态内部类对外部类的静态成员方法可以访问 53 method3(); 54 method4(); 55 } 56 } 57 }
1 package cn.temptation; 2 3 public class Sample11 { 4 public static void main(String[] args) { 5 // 静态内部类有构造函数,并且创建时可以选择相应的构造函数重载方法 6 7 OuterClass11.InnerClass11 inner1 = new OuterClass11.InnerClass11(); 8 System.out.println(inner1); 9 10 OuterClass11.InnerClass11 inner2 = new OuterClass11.InnerClass11("param"); 11 System.out.println(inner2); 12 } 13 } 14 15 // 外部类 16 class OuterClass11 { 17 // 成员内部类 18 static class InnerClass11 { 19 // 构造函数 20 public InnerClass11() { 21 System.out.println("这是内部类的无参构造函数"); 22 } 23 24 public InnerClass11(String str) { 25 System.out.println("这是内部类的有参构造函数,参数为:" + str); 26 } 27 } 28 }
1 package cn.temptation; 2 3 public class Sample12 { 4 public static void main(String[] args) { 5 // 3、局部内部类:联想到局部变量,位于外部类的成员方法中 6 7 // 观察一下生成的字节码文件,有三个:Sample12.class、OuterClass12.class、OuterClass12$1InnerClass12.class 8 // 局部内部类字节码名称为 外部类名称$ 编号 局部内部类名称.class 9 10 // 语法错误:InnerClass12 cannot be resolved to a type 11 // InnerClass12 innerClass12 = new InnerClass12(); 12 13 // 语法错误:OuterClass12.InnerClass12 cannot be resolved to a type 14 // OuterClass12.InnerClass12 innerClass12 = new OuterClass12.new InnerClass12(); 15 16 // 对于局部内部类的访问,只能通过其所在的外部类的成员方法的调用 17 OuterClass12 outerClass12 = new OuterClass12(); 18 outerClass12.showByOuter(); // 局部内部类的成员方法 19 } 20 } 21 22 // 外部类 23 class OuterClass12 { 24 // 成员方法 25 public void showByOuter() { 26 // 局部内部类 27 class InnerClass12 { 28 // 成员方法 29 public void showByInner() { 30 System.out.println("局部内部类的成员方法"); 31 } 32 } 33 34 // 在外部类的成员方法中实例化局部内部类对象 35 InnerClass12 innerClass12 = new InnerClass12(); 36 innerClass12.showByInner(); 37 } 38 }
1 package cn.temptation; 2 3 public class Sample13 { 4 public static void main(String[] args) { 5 // 局部内部类的特点: 6 // 1、局部内部类中可以直接访问所在的外部类的成员 7 // 2、局部内部类中可以直接访问所在的外部类的非静态的成员变量 和 静态的成员变量 8 } 9 } 10 11 // 外部类 12 class OuterClass13 { 13 // 非静态的成员变量 14 public int i = 2; 15 private int j = 3; 16 // 静态的成员变量 17 public static int x = 4; 18 private static int y = 5; 19 20 // 成员方法 21 public void showByOuter() { 22 // 局部内部类 23 class InnerClass13 { 24 // 成员方法 25 public void showByInner() { 26 // 局部内部类对于所在的外部类的成员变量均可以访问(不论是用public修饰的,还是用private修饰的) 27 System.out.println(i); 28 System.out.println(j); 29 // 局部内部类对于所在的外部类的静态成员变量均可以访问(不论是用public修饰的,还是用private修饰的) 30 System.out.println(x); 31 System.out.println(y); 32 } 33 } 34 35 // 在外部类的成员方法中实例化局部内部类对象 36 InnerClass13 innerClass13 = new InnerClass13(); 37 innerClass13.showByInner(); 38 } 39 }
1 package cn.temptation; 2 3 public class Sample14 { 4 public static void main(String[] args) { 5 // 局部内部类的特点: 6 // 1、局部内部类中可以直接访问所在的外部类的非静态的成员方法 和 静态的成员方法 7 } 8 } 9 10 // 外部类 11 class OuterClass14 { 12 // 成员方法 13 public void method1() { 14 System.out.println("外部类的公有非静态成员方法"); 15 } 16 17 private void method2() { 18 System.out.println("外部类的私有非静态成员方法"); 19 } 20 21 public static void method3() { 22 System.out.println("外部类的公有静态成员方法"); 23 } 24 25 private static void method4() { 26 System.out.println("外部类的私有静态成员方法"); 27 } 28 29 // 成员方法 30 public void showByOuter() { 31 // 局部内部类 32 class InnerClass14 { 33 // 成员方法 34 public void showByInner() { 35 // 局部内部类对于所在的外部类的成员方法均可以访问(不论是用public修饰的,还是用private修饰的) 36 method1(); 37 method2(); 38 // 局部内部类对于所在的外部类的静态成员方法均可以访问(不论是用public修饰的,还是用private修饰的) 39 method3(); 40 method4(); 41 } 42 } 43 44 // 在外部类的成员方法中实例化局部内部类对象 45 InnerClass14 innerClass14 = new InnerClass14(); 46 innerClass14.showByInner(); 47 } 48 }
1 package cn.temptation; 2 3 public class Sample15 { 4 public static void main(String[] args) { 5 // 局部内部类有构造函数,并且创建时可以选择相应的构造函数重载方法 6 7 OuterClass15 outerClass15 = new OuterClass15(); 8 outerClass15.showByOuter(); 9 } 10 } 11 12 // 外部类 13 class OuterClass15 { 14 // 成员方法 15 public void showByOuter() { 16 // 局部内部类 17 class InnerClass15 { 18 // 构造函数 19 public InnerClass15() { 20 System.out.println("局部内部类的无参构造函数"); 21 } 22 23 public InnerClass15(String str) { 24 System.out.println("局部内部类的有参构造函数,参数为:" + str); 25 } 26 } 27 28 // 在外部类的成员方法中实例化局部内部类对象 29 InnerClass15 inner1 = new InnerClass15(); 30 System.out.println(inner1); 31 32 InnerClass15 inner2 = new InnerClass15("param"); 33 System.out.println(inner2); 34 } 35 }
1 package cn.temptation; 2 3 public class Sample16 { 4 public static void main(String[] args) { 5 // 观察一下生成的字节码文件,有四个:Sample16.class、OuterClass16.class、OuterClass16$1InnerClass16.class、OuterClass16$2InnerClass16.class 6 // 局部内部类字节码名称为 外部类名称$ 编号 局部内部类名称.class 7 8 OuterClass16 outerClass16 = new OuterClass16(); 9 outerClass16.metho1ByOuter(); 10 outerClass16.metho2ByOuter(); 11 12 // 注意:在外部类的不同成员方法中可以定义相同名称的局部内部类名称(即局部内部类可以重名),但是成员内部类 和 静态内部类 不可以重名(在同一个外部类中) 13 } 14 } 15 16 // 外部类 17 class OuterClass16 { 18 // 成员方法 19 public void metho1ByOuter() { 20 // 局部内部类 21 class InnerClass16 { 22 23 } 24 25 // 在外部类的成员方法中实例化局部内部类对象 26 InnerClass16 inner1 = new InnerClass16(); 27 System.out.println(inner1); 28 } 29 30 public void metho2ByOuter() { 31 // 局部内部类 32 class InnerClass16 { 33 34 } 35 36 // 在外部类的成员方法中实例化局部内部类对象 37 InnerClass16 inner2 = new InnerClass16(); 38 System.out.println(inner2); 39 } 40 }
1 package cn.temptation; 2 3 public class Sample17 { 4 public static void main(String[] args) { 5 // 局部内部类的成员方法访问局部内部类所在的外部类的成员方法中定义的局部变量,局部变量可以使用final修饰,也可以不使用final修饰 6 // 但是不论是否使用final修饰,效果等同于使用final修饰 7 8 OuterClass17 outerClass17 = new OuterClass17(); 9 outerClass17.showByOuter(); 10 } 11 } 12 13 // 外部类 14 class OuterClass17 { 15 // 成员方法 16 public void showByOuter() { 17 // 局部变量 18 int i = 2; 19 final int j = 3; 20 21 // 局部内部类 22 class InnerClass17 { 23 // 成员方法 24 public void showByInner() { 25 // 注意:下句从JDK 1.8开始不会产生错误,之前的JDK版本会产生语法错误 26 System.out.println(i); // 2 27 System.out.println(j); // 3 28 29 // 语法错误:Local variable i defined in an enclosing scope must be final or effectively final 30 // 局部内部类中的成员方法访问所在的成员方法的局部变量,该局部变量使用final定义或等同于final修饰的效果 31 // i = 4; 32 // System.out.println(i); 33 34 // 语法错误: The final local variable j cannot be assigned, since it is defined in an enclosing type 35 // j = 5; 36 // System.out.println(j); 37 } 38 } 39 40 // 在外部类的成员方法中实例化局部内部类对象 41 InnerClass17 innerClass17 = new InnerClass17(); 42 innerClass17.showByInner(); 43 } 44 }
1 package cn.temptation; 2 3 public class Sample18 { 4 public static void main(String[] args) { 5 // 4、匿名内部类:联想到匿名对象和匿名数组,内部类没有名称,需要存在一个类或接口 6 7 // 观察一下生成的字节码文件,有三个:Foo.class、Sample18.class、OuterClass18.class、OuterClass18$1.class 8 // 匿名内部类字节码名称为 外部类名称$编号.class 9 10 // 创建匿名内部类对象的方式:通过调用匿名内部类所在的外部类的成员方法 11 OuterClass18 outerClass18 = new OuterClass18(); 12 // 定义接口类型的变量来接收匿名内部类对象的返回 13 Foo foo = outerClass18.showByOuter(); 14 System.out.println(foo); // cn.temptation.OuterClass18$1@15db9742 15 } 16 } 17 18 // 定义接口 19 interface Foo { 20 public abstract void show(); 21 } 22 23 // 接口的实现类 24 //class FooImpl implements Foo { 25 // @Override 26 // public void show() { 27 // System.out.println("接口的实现类的成员方法"); 28 // } 29 //} 30 31 // 外部类 32 class OuterClass18 { 33 // 成员方法 34 public Foo showByOuter() { 35 // 实现了Foo接口的匿名内部类(类似局部内部类的位置) 36 return new Foo() { 37 @Override 38 public void show() { 39 System.out.println("实现了接口的匿名内部类"); 40 } 41 }; 42 } 43 }
1 package cn.temptation; 2 3 public class Sample19 { 4 public static void main(String[] args) { 5 // 匿名内部类的特点: 6 // 1、匿名内部类没有构造函数的(使用者无法创建构造函数,其实JVM生成了构造函数) 7 } 8 } 9 10 // 定义接口 11 interface Test { 12 public abstract void show(); 13 } 14 15 // 外部类 16 class OuterClass19 { 17 // 成员方法 18 public Test showByOuter() { 19 // 实现了Foo接口的匿名内部类 20 return new Test() { 21 // 构造函数 22 // Return type for the method is missing 23 // public Test() { 24 // 25 // } 26 27 // 成员方法 28 @Override 29 public void show() { 30 System.out.println("实现了接口的匿名内部类"); 31 } 32 }; 33 } 34 } 35 // 查看OuterClass19$1.class字节码文件的反编译,可以看出jvm帮我们匿名内部类起了名字,并且生成了构造函数 36 //class OuterClass19$1 implements Test { 37 // final OuterClass19 this$0; 38 // 39 // public void show() 40 // { 41 // System.out.println("实现了接口的匿名内部类"); 42 // } 43 // 44 // OuterClass19$1() 45 // { 46 // this$0 = OuterClass19.this; 47 // super(); 48 // } 49 //}
1 package cn.temptation; 2 3 public class Sample20 { 4 public static void main(String[] args) { 5 // 匿名内部类的方法调用 6 OuterClass20 outerClass20 = new OuterClass20(); 7 outerClass20.showByOuter(); 8 } 9 } 10 11 // 定义接口 12 interface Demo { 13 public abstract void show(); 14 } 15 16 class DemoImpl implements Demo { 17 @Override 18 public void show() { 19 System.out.println("这是接口定义的方法"); 20 } 21 } 22 23 // 外部类 24 class OuterClass20 { 25 // 成员方法 26 public void showByOuter() { 27 // 匿名内部类的方法回调 28 (new Demo() { 29 @Override 30 public void show() { 31 System.out.println("这是接口定义的方法"); 32 } 33 }).show(); 34 35 // 上述方法回调的写法本质就是如下写法 36 Demo obj = new DemoImpl(); 37 obj.show(); 38 } 39 }
1 package cn.temptation; 2 3 public class Sample21 { 4 public static void main(String[] args) { 5 OuterClass21 outerClass21 = new OuterClass21(); 6 outerClass21.showByOuter(); 7 } 8 } 9 10 // 接口 11 interface Ability { 12 public abstract void method1(); 13 public abstract void method2(); 14 } 15 16 // 外部类 17 class OuterClass21 { 18 // 成员方法 19 public void showByOuter() { 20 // 接口定义的一个方法的调用 21 // (new Ability() { 22 // @Override 23 // public void method1() { 24 // System.out.println("接口定义的方法1"); 25 // } 26 // 27 // @Override 28 // public void method2() { 29 // System.out.println("接口定义的方法2"); 30 // } 31 // }).method1(); 32 33 // 接口定义的两个方法的调用的写法1(分别调用) 34 // (new Ability() { 35 // @Override 36 // public void method1() { 37 // System.out.println("接口定义的方法1"); 38 // } 39 // 40 // @Override 41 // public void method2() { 42 // System.out.println("接口定义的方法2"); 43 // } 44 // }).method1(); 45 // 46 // (new Ability() { 47 // @Override 48 // public void method1() { 49 // System.out.println("接口定义的方法1"); 50 // } 51 // 52 // @Override 53 // public void method2() { 54 // System.out.println("接口定义的方法2"); 55 // } 56 // }).method2(); 57 58 // 接口定义的两个方法的调用的写法2(定义一个接口类型的变量来接收匿名内部类) 59 Ability obj = new Ability() { 60 @Override 61 public void method1() { 62 System.out.println("接口定义的方法1"); 63 } 64 65 @Override 66 public void method2() { 67 System.out.println("接口定义的方法2"); 68 } 69 }; 70 71 obj.method1(); 72 obj.method2(); 73 } 74 }
1 package cn.temptation; 2 3 public class Sample22 { 4 public static void main(String[] args) { 5 OuterClass22 outerClass22 = new OuterClass22(); 6 outerClass22.showByOuter(); 7 } 8 } 9 10 // 接口 11 interface Project { 12 public abstract void show(); 13 } 14 15 // 外部类 16 class OuterClass22 { 17 // 成员变量 18 public int i = 2; 19 private int j = 3; 20 public static int x = 4; 21 public static int y = 5; 22 23 // 成员方法 24 public void showByOuter() { 25 // 匿名内部类 26 (new Project() { 27 // 成员方法 28 @Override 29 public void show() { 30 // 匿名内部类可以访问外部类的成员变量(不论是否公有私有、不论是否静态非静态) 31 System.out.println(i); 32 System.out.println(j); 33 System.out.println(x); 34 System.out.println(y); 35 } 36 }).show(); 37 } 38 }
1 package cn.temptation; 2 3 public class Sample23 { 4 public static void main(String[] args) { 5 // 需求:运用内部类,描述如下功能:张三有一颗健壮的心脏,他最近想靠搬砖发财 6 7 // 思路: 8 // 1、"张三有一颗健壮的心脏":考虑使用成员内部类,并且只有一颗心脏(考虑使用单例获取) 9 // 2、"他最近想靠搬砖发财":考虑使用匿名内部类 10 11 Person person = new Person("张三"); 12 Person.Heart heart = person.getInstance(); 13 heart.setState("健壮"); 14 System.out.println("姓名为:" + person.getName() + ",有一颗" + heart.getState() + "的心脏"); 15 16 person.think("搬砖"); 17 } 18 } 19 20 // 接口 21 interface IAbility { 22 public abstract void getRich(String str); 23 } 24 25 // 外部类:人类 26 class Person { 27 // 成员变量 28 private String name; 29 private Heart heart; 30 31 // 构造函数 32 public Person() { 33 super(); 34 } 35 36 public Person(String name) { 37 super(); 38 this.name = name; 39 } 40 41 // 成员内部类:心脏类 42 class Heart { 43 // 成员变量 44 private String state; 45 46 // 构造函数 47 private Heart() { 48 super(); 49 } 50 51 // 成员方法 52 public String getState() { 53 return state; 54 } 55 56 public void setState(String state) { 57 this.state = state; 58 } 59 } 60 61 // 成员方法 62 public String getName() { 63 return name; 64 } 65 66 public void setName(String name) { 67 this.name = name; 68 } 69 70 // 自定义成员方法 71 public Heart getInstance() { 72 if (heart == null) { 73 heart = new Heart(); 74 } 75 76 return heart; 77 } 78 79 public void think(String str) { 80 // 匿名内部类 81 (new IAbility() { 82 @Override 83 public void getRich(String str) { 84 System.out.println("依靠" + str + "发财"); 85 } 86 }).getRich(str); 87 } 88 }