七(2)、内部类

一、匿名内部类

关于上一章介绍了成员内部类和局部内部类, 下面介绍内部类的第三种形态:匿名内部类。匿名内部类,顾名思义,就是没有名字的内部类.

匿名内部类可以作用在类上,也可以作用在接口上

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

个人理解,嵌套类不重要,用的少

时间: 08-04

七(2)、内部类的相关文章

Think in Java(七):内部类

1. 内部类访问外部类的成员变量:Outer.this.size public class Outer { private int size; public class Inner1 { private int size; public void display(int size) { size++; // 引用的是display函数的形参 this.size++; // 引用的是Inner类中的成员变量 Outer.this.size++; // 引用的是Outer类中的成员变量 } } }

七、内部类

一.内部类的定义 把一个类比喻成一个人, 组合.继承.接口等啊就是“朝外”发展自己的这个意味, 而内部类则可以认为是“朝内”提升的这个意味. 内部类的定义是:将一个类的定义写在另一个类的内部,它可以方便的将一些相关的类组织在一起, 并且控制其只在内部可见. 二.内部类分类 内部类可以分为三种:成员内部类, 局部内部类, 匿名内部类.  成员内部类就是定义在一个类的内部的类,位置与成员变量相当: 局部内部类就是定义在一个方法内部的,位置与局部变量相当. 1 public class Test {

黑马程序员——面向对象(一)概述、类与对象、继承、抽象类、接口、多态、内部类

一.面向对象概述 1.面向对象:是一个很抽象的概念,它相对面向过程而言,是一种程序设计的思想. 2.面向对象的特点: * 符合人们思考习惯的思想 * 可以将复杂的事情简单化 * 将程序员从执行者转换成了指挥者 * 完成需求时:只需要寻找具备所需功能的对象或者创建所需功能的对象即可,简化开发效率并提高对象的复用性. 3.面向对象的三个特征:封装(Encapsulation).继承(Inheritance).多态(Polymorphism). 二.类与对象 (一)类与对象之间的关系 1.类的定义:类

Java中的内部类怎么用

一.为什么需要内部类?java内部类有什么好处?为什么需要内部类? 首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口.由于内部类对外部类的所有内容都是可访问的,所以这 样做可以完成所有你直接实现这个接口的功能. 不过你可能要质疑,更改一下方法的不就行了吗? 的确,以此作为设计内部类的理由,实在没有说服力. 真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++

Android学习笔记(四) JAVA基础知识回顾

一.接口 1)接口中定义的方法都是public权限,并且默认为public,而不是default. 2)接口的实现(implements)是特殊的继承,类似于父类子类的关系,可以向上转型(非常重要). 3)一个类可以实现多个接口:一个接口可以继承多个接口. 二.静态变量/方法 1)如果某方法(或变量)声明为static,则可以直接使用"类名.方法名(或变量名)"调用. 2)静态方法只能使用静态变量. 三.静态工厂模式 核心思想:把生成对象的代码(使用new来调用构造函数的方法)封装在工

Java学习笔记-4.继承与多态

一.继承机制 1.继承:允许一个类作为另一个类的扩充版本 2.单继承:一个类只继承了一个父类    多继承:一个类继承了多个父类 Java只支持单继承,C++支持多继承 二.类的继承 1.形式: class SubClass extends BaseClass { //子类类体,定义子类的新成员 } Java中所有的类都直接或间接地继承类 java.lang.Object 2.构造方法 (1)显式构造方法    形式:super(参数表); 系统执行到这条语句时,会根据参数表判断调用父类中哪个构

20165330 2017-2018-2 《Java程序设计》第5周学习总结

课本知识总结 第七章 内部类与异常类 内部类:类的一种成员 外嵌类:包含内部类的类称为内部类的外嵌类 二者关系: 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法. 内部类的类体中不可以声明类变量和类方法.外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员. 内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象. 内部类可以修饰为static内部类 static内部类不能操作外嵌类中的实例成员变量 内部类对应的字节码文件名字格式:外嵌类名$内部类名

20165203《Java程序设计》第五周学习总结

教材学习内容总结 第七章 内部类 注意内部类和外嵌类的关系: 外嵌类的成员变量和方法在内部类有效 内部类的类体不可以声明static变量和方法.外嵌类的类体可以用内部类声明对象. 内部类仅供它的外嵌类使用,其他类不可以. 匿名类 直接使用子类的类体创建一个子类对象. 匿名类可以继承父类的方法也可以重写父类的方法. 匿名类一定是内部类. 匿名类可以访问外嵌类中的成员变量和方法,但自身类体不可以有static成员变量和方法. 用匿名类创建对象时,要直接使用父类的构造方法. 和接口有关的匿名类:如果某

20165318 2017-2018-2 《Java程序设计》第五周学习总结

20165318 2017-2018-2 <Java程序设计>第五周学习总结 学习总结 在使用IDEA时,由于我之前编写的代码都是使用GBK编码,使用IDEA打开时,由于IDEA默认为UTF-8,代码会出现中文乱码,这时候可以使用如下方法,将IDEA的编码改成GBK 教材内容总结: 第七章 内部类与异常类 一. 内部类与匿名类 内部类: 1.内部类可以使用外嵌类的成员变量和方法. 2.类体中不可以声明类变量和类方法. 3.内部类仅供外嵌类使用. 4.类声明可以使用static修饰,static

20165230 2017-2018-2 《Java程序设计》第5周学习总结

20165230 2017-2018-2 <Java程序设计>第5周学习总结 教材学习内容总结 第七章 内部类与异常类 内部类与外嵌类 可以在类中定义另一个类,即内部类 包含内部类的类为内部类的外嵌类 外嵌类的成员变量在内部类中有效,类体中可用内部类声明对象 内嵌类的类体中不可以声明类变量和类方法,内部类中的方法可调用外嵌类的方法 内部类仅供外嵌类使用 内部类可为static内部类,即可用外嵌类.内部类的访问内部类,不可操作外嵌类中的实例成员变量 匿名类 创建和子类有关的匿名类对象: new