一、匿名内部类
关于上一章介绍了成员内部类和局部内部类, 下面介绍内部类的第三种形态:匿名内部类。匿名内部类,顾名思义,就是没有名字的内部类.
匿名内部类可以作用在类上,也可以作用在接口上
1.匿名内部类作用在类上
1 package method2; 2 3 public class Test3 { 4 private int i=2; 5 public int value() { 6 System.out.println(this.getClass().getSimpleName()+"在外部");//* 7 return i; 8 } 9 public Test3 getTest3() { 10 return new Test3() { 11 private int i=1; 12 public int value() { 13 System.out.println(this.getClass().getSimpleName()+"内部");//** 14 return i; 15 } 16 }; 17 } 18 19 public static void main(String[]args) { 20 Test3 t = new Test3(); 21 System.out.println(t.value()); 22 23 Test3 t2 = t.getTest3();//这里产生的是匿名内部类 24 System.out.println(t2.value()); 25 } 26 }
结果如下:
虽然已经有了Test3的具体类,但是getTest3()中还是可以直接return new Test(){}这种方式来返回内部类, 并且用Test3的声明能够接收这个内部类,所以这个内部类是属于Test3的子类。 另一点: 匿名内部类中使用this.getClass().getSimpleName()方法返回的是空,说明匿名内部类是没有方法名的。
现实中,用匿名内部类作用在类的情况还是不多见的。 下一种作用在接口上的你匿名内部类更常见
2.匿名内部类作用在接口上
1 package method2; 2 3 public interface Processor { 4 public void method(); 5 } 6 7 8 package method2; 9 10 public class Test4 { 11 public static void main(String[]args) { 12 Test4 t = new Test4(); 13 Processor p = t.f(); 14 p.method(); 15 } 16 17 public Processor f() { 18 return new Processor() { //直接写new 接口名 ,然后加方法方法体的形式 19 public void method() { 20 System.out.println("实现method"); 21 } 22 }; 23 } 24 }
3.匿名内部类也可以传参
1 package method2; 2 3 public class Test3 { 4 private int i=2; 5 public int value() { 6 System.out.println(this.getClass().getSimpleName()+"在外部"); 7 return i; 8 } 9 10 public Test3() { 11 12 } 13 14 public Test3(int k) { 15 this.i = k; 16 } 17 18 public Test3 getTest3(final int k) { 19 return new Test3(k) {//匿名内部类可以传递参数,但是要求参数本身是final的 20 private int i= k; 21 public int value() { 22 System.out.println(this.getClass().getSimpleName()+"内部"); 23 return i; 24 } 25 }; 26 } 27 28 public static void main(String[]args) { 29 Test3 t = new Test3(); 30 System.out.println(t.value()); 31 32 Test3 t2 = t.getTest3(3); 33 System.out.println(t2.value()); 34 } 35 }
特别要注意的是匿名内部类传参,要求参数必须为final的
二、匿名内部类结合工厂模式
1 public class Test3 { 2 public static void main(String[] args) { 3 A a = Factory.newInstance(); 4 a.f(); 5 } 6 } 7 8 class Factory { 9 public static A newInstance() { 10 return new A() { 11 @Override 12 public void f() { 13 System.out.println("haha"); 14 } 15 }; 16 } 17 } 18 19 interface A { 20 void f(); 21 }
将匿名内部类应用到工厂模式中,对于可能只要使用一次的产品,是很好的选择
三、嵌套类
1.前面讲过,创建普通的内部类, 内部类是持有外部类的引用的 ,外部内也持有内部类的引用(可以参见上一章),嵌套类其实就是内部类用static修饰的情况(可以跳过这个例子)
1 public class Test3 { 2 public static void main(String[] args) { 3 // TT.f();//这么写报错,虽然说嵌套类可以不依赖MM的对象存在,但是还是依赖MM的类存在,毕竟TT是在MM内部,不能直接写TT.f() 4 MM.TT.f(); 5 // MM.TT.m();//这里会报错,没有具体对象存在,只能够访问静态方法 6 7 MM.TT t = new MM.TT(); 8 t.m();//m方法是非静态的,需要创建了TT的对象才能使用 9 10 MM.TT t2 = new MM.TT(); 11 System.out.println("equals?:"+(t==t2)); 12 } 13 14 15 } 16 17 18 class MM { 19 static int i = 1; 20 int j = 2; 21 public static class TT { 22 public static void f() { 23 System.out.println("ff:"+i);//嵌套类中,只能够使用外部static的变量,这里调用j会报错 24 } 25 26 public void m() { 27 System.out.println("mm"); 28 } 29 } 30 }
结果如下:
嵌套类的这个例子很有趣,嵌套类虽然是声明为static的,但是它也是需要外围类来查询的MM.TT
另外嵌套类还可以被new出来,而且从结果上看他们是不同的对象。 但是这些都不重要, 工作中肯定不会碰到嵌套类的这种用法。
如果想要创建某种公共代码,使得它们可以被某个接口的所有不同的实现所公用, 这个时候就适合使用嵌套类了。
1 interface Test4 { 2 public static class Check { 3 public static void test(Object obj) {//这里打印出来类名 4 System.out.println(obj.getClass().getSimpleName()); 5 } 6 } 7 } 8 9 10 public class Test3 implements Test4 { 11 public static void main(String[] args) { 12 Test4.Check.test(new Test3()); 13 } 14 }
所有实现Test4接口的类,都会公用Check
个人理解,嵌套类不重要,用的少
时间: 2024-10-25 05:31:12