第十章:内部类(下)
来源:互联网 发布:java 正则表达式 负数 编辑:程序博客网 时间:2024/06/05 09:45
10.8 为什么需要内部类
每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对内部类没有影响。内部类提供可以继承多个具体的或抽象的类的能力。
10.8.1 闭包与回调
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来源于创建它的作用域。内部类是面向对象的闭包。
大家自己欣赏一下代码:
// 接口interface Incrementable { void increment();}// 外部类实现接口class Callee1 implements Incrementable { private int i = 0; public void increment() { i++; System.out.println(i); }}// 类class MyIncrement { public void increment() { System.out.println("Other operation"); } static void f(MyIncrement mi) { mi.increment(); }}// If your class must implement increment() in// some other way, you must use an inner class:class Callee2 extends MyIncrement { private int i = 0; public void increment() { super.increment(); i++; System.out.println(i); } // 内部类实现接口 private class Closure implements Incrementable { public void increment() { // Specify outer-class method, otherwise you'd get an infinite recursion: Callee2.this.increment(); } } // 返回实现了Incrementable类的对象 Incrementable getCallbackReference() { return new Closure(); }}class Caller { private Incrementable callbackReference; Caller(Incrementable cbh) { callbackReference = cbh; } void go() { callbackReference.increment(); }}public class Callbacks { public static void main(String[] args) { Callee1 c1 = new Callee1(); Callee2 c2 = new Callee2(); MyIncrement.f(c2); Caller caller1 = new Caller(c1); Caller caller2 = new Caller(c2.getCallbackReference()); caller1.go(); caller1.go(); caller2.go(); caller2.go(); }}
10.8.2 内部类与控制框架
设计模式总是将变化的事物与不变的事物分离开来。
10.9 内部类的继承
class WithInner { private int i; class Inner { public Inner() { System.out.println("我是内部类构造函数!"); } }}public class InheritInner extends WithInner.Inner { public InheritInner(WithInner withInner) { // 必须加上这句话否则编译错误 withInner.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); }}
内部类持有外部类的引用。在继承内部类的时候,那个指向外部类对象的“秘密的”引用必须被初始化。所以必须在子类的构造器使用如下语法:
enclosingClassReference.super();
这样才提供了必要的引用,程序才可以编译通过。
10.10 内部类可以被覆盖吗
答案当然是不可以,覆盖只是针对于方法而言的。
10.11 局部内部类
局部内部类不能有访问说明符,因为他不是外部类的一部分;但是他可以访问当前代码块内的常量,以及此外部类的所有成员。
interface Counter { int next();}public class LocalInnerClass { private int count = 0; Counter getCounter(final String name) { // 局部内部类 class LocalCounter implements Counter { public LocalCounter() { // Local inner class can have a constructor System.out.println("LocalCounter()"); } public int next() { System.out.println(name); // Access local final return count++; } } return new LocalCounter(); } // The same thing with an anonymous inner class: // 返回匿名内部类 Counter getCounter2(final String name) { return new Counter() { // Anonymous inner class cannot have a named // constructor, only an instance initializer: { System.out.println("Counter()"); } public int next() { System.out.println(name); // Access local final return count++; } }; } public static void main(String[] args) { LocalInnerClass lic = new LocalInnerClass(); Counter c1 = lic.getCounter("Local inner "), c2 = lic.getCounter2("Anonymous inner "); for (int i = 0; i < 5; i++) System.out.println(c1.next()); for (int i = 0; i < 5; i++) System.out.println(c2.next()); }}
既然局部内部类的名字在方法外是不可见的,那为什么我们仍然使用局部内部类而不是匿名内部类呢?唯一的理由是:我们需要一个已经命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例的初始化
,所以使用局部内部类而不使用匿名内部类的另一个理由是,需要不止一个内部类对象
。局部内部类更灵活。
10.12 内部类标识符
每个类都会生成 .class 文件,那么内部类的 .class 文件叫什么名字呢?
普通内部类:外部类的名称$内部类的名称.class
匿名内部类:外部类的名称$数字.class【使用数字作为其标识符】
如果是多个内部类嵌套:外部类的名称$内部类的名称$内部类的名称… .class
每个内部类都会单独生成一个 .class 文件
0 0
- 第十章 内部类(下)
- 第十章:内部类(下)
- java编程思想读书笔记 第十章 内部类(下)
- 第十章:内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章 内部类
- 第十章:内部类
- 第十章:内部类
- 第十章 内部类(上)
- 第十章:内部类(上)
- 第十章 多态 & 内部类
- 第十章 内部类 内部类和嵌套类
- test
- Android入门级之Button的使用
- SQL SERVER日常运维巡检系列之四——数据库备份
- HDU-5919 Sequence II
- hadoop中namenode无法启动
- 第十章:内部类(下)
- 页面跳转,文档载入整个浏览器窗口
- Linux 配置双机SSH信任
- jQuery(一)
- Android 6.0新特性
- 如何设置Android手机的sqlite3命令环境
- Android 在 Java 代码中实现布局
- 正则表达式 例子
- Android Volley完全解析(二),使用Volley加载网络图片