public class Test {
    public static void main(String[] args) {
        Callbacks.test();
    }
}

/*
    为什么需要内部类:
        1.可以认为内部类提供了某种进入外围类的窗口
        2.每个内部类都能独立的继承一个接口的实现,所以无论外围类是否已经继承了某个
        接口的实现,对于内部类都是没有影响的
        3.可以解决多重继承的问题

    内部类一些其他的优点:
        1.内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外围类对象的信息相互独立
        2.在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
        3.创建内部类对象的时刻并不依赖外部类对象的创建(这个有问题吧?)
        4.内部类没有令人疑惑的“is-a”关系,它就是一个独立的实体
 */
interface A { }
interface B { }
class X implements A,B{}
class Y implements A{
    B makeB(){return new B(){}; };
}

class D {}
abstract class E {}
class Z extends D{
    E makeE(){ return new E(){}; }
}

/*
    需求:
        人们认为Java应该包含某种类似指针的机制,以允许回调。通过回调,对象能够携带
        一些信息,这些信息允许它在稍后的某个时刻调用初始的对象。(将函数指针传给这
        个对象,然后由这个对象通过函数指针调用初始对象的方法。)

    案例分析:
        我感觉这个案例好复杂啊,莫名奇妙的类关系。Callee翻译为被召集者,Caller翻译为
        召集者。召集者手中持有一个实现了Increment的对象,用来记录自己召集的人被召集了
        多少次,这就想每个包工头手上有一个人,它分配活给这个工人,同时还要记录下这个工
        人干了多少次活。对于callee1,它直接实现了Increment接口,从单一职能的设计原
        则上来讲,这种设计分工并不明确。对于callee2,由于系统强迫它继承了MyIncrement
        (这其中涉及到方法名冲突方面的问题,我还没看到这部分,理论上,我觉得也可以去实现
        一下Increment接口,做实验也确实可以),而且MyIncrement有个方法,系统要求必须
        在数据增加时调用,这时候我们就使用回调了
 */

interface Incrementable {
    void increment();
}

/*
    一种非常简陋的方案
 */
class Callee1 implements Incrementable {
    private int i = 0;
    @Override
    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();}
}

class Callee2  extends MyIncrement{
    private int i = 0;

    public void increment() {
        super.increment();
        i++;
        System.out.println(i);
    }

    private class Closure implements Incrementable {
        @Override
        public void increment() {
            Callee2.this.increment();
        }
    }

    Incrementable getCallbackReference() {
        return new Closure();
    }
}

/*
    需求部分
 */

class Caller{
    private Incrementable callbackReference;

    public Caller(Incrementable callbackReference) {
        this.callbackReference = callbackReference;
    }

    void go() {
        callbackReference.increment();
    }
}

class Callbacks {
    public static void test() {
        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();
    }
}

Java编程思想:为什么要使用内部类的更多相关文章

  1. Java编程思想学习(八) 内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类的定义是简单的,但是它的语法确实很是复杂,让人不是很好理解.下面就内部类做一个小结. 一.内部类的分类 总的来讲内部类分为普通内部类,匿 ...

  2. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  3. Java编程思想读书笔记之内部类

    现在是够懒得了,放假的时候就想把这篇笔记写出来,一直拖到现在,最近在读<Java编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始 ...

  4. java编程思想

    Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...

  5. Java编程思想 (1~10)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象2.程序就是对象的集合3.每个对象都是由其它对象所构成 ...

  6. Java 编程思想 Chapter_14 类型信息

    本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...

  7. Java编程思想(前十章)

    Java编程思想 有C++编程基础的条件下, 前10章可以快速过一下,都是基本语法,不需要花太多时间. 着重中后段的一些章节,类型信息.泛型.容器.IO.并发等. 中文翻译版 阅读地址 对于一个架构师 ...

  8. 《Java编程思想第四版完整中文高清版.pdf》-笔记

    D.2.1 安插自己的测试代码 插入下述“显式”计时代码,对程序进行评测: long start = System.currentTimeMillis(); // 要计时的运算代码放在这儿 long ...

  9. 《Java编程思想第四版》附录 B 对比 C++和 Java

    <Java编程思想第四版完整中文高清版.pdf>-笔记 附录 B 对比 C++和 Java “作为一名 C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且 Java 的语法无疑是 ...

  10. Java编程思想中关于闭包的一个例子

    Java编程思想中的一个例子,不是很理解使用闭包的必要性,如果不使用闭包,是不是有些任务就不能完成?继续探索. package InnerClass; interface Incrementable ...

随机推荐

  1. Silverlight DataGrid自适应数据

    silverlight的DataGrid如果改成fill模式 那么当数据超长也不会出现横向滚动条 如果改成按单元格模式 如果数据较短又会出现空白的地方 所以我自己写了个算法 目前实现了以list为数据 ...

  2. delphi 程序强制结束自身(两种方法都暴力)

    procedure KillSelf;begin  Sleep(1000);  if not TerminateProcess(GetCurrentProcessId, 0) then  WinExe ...

  3. Windows的远程协助和远程桌面的区别

    在Windows的“系统属性-远程”里面,包含了“远程协助”和“远程桌面”两个设置. 远程桌面我们平时用得比较多,但是远程协助却一直没明白什么作用.系统装完以后,“远程协助 - 允许远程协助连接这台计 ...

  4. Failed to recover corrupt cache entry

    RangeError java.lang.RuntimeException: ERROR: Failed to recover corrupt cache entry at com.sun.deplo ...

  5. 【Python】:拓展Queue实现有序不重复队列

    最近手头有个需求是这样的,定期检查数据库获取失败任务并且进行重启.最早想到的是添加一个生产者&&消费者队列,但是发现很多棘手的问题. 1.重启任务是调用的一个shell脚本然后在脚本中 ...

  6. 线性回归模型(Linear Regression)及Python实现

    线性回归模型(Linear Regression)及Python实现 http://www.cnblogs.com/sumai 1.模型 对于一份数据,它有两个变量,分别是Petal.Width和Se ...

  7. 彻底弄懂UTF-8、Unicode、宽字符、locale

    目录 Unicode.UCS UTF8 宽字符类型wchar_t locale 为什么需要宽字符类型 多字节字符串和宽字符串相互转换 最近使用到了wchar_t类型,所以准备详细探究下,没想到水还挺深 ...

  8. 跟着大彬读源码 - Redis 2 - 服务器如何响应客户端请求?(上)

    上次我们通过问题"启动服务器,程序都干了什么?",跟着源码,深入了解了 Redis 服务器的启动过程. 既然启动了 Redis 服务器,那我们就要连上 Redis 服务干些事情.这 ...

  9. CentOs7.5安装FFmpeg

    一.FFmpeg简介 FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec ─这是一个用于多个项目中音频和视频的解码器库,以及libavformat— ...

  10. HDU 6207:Apple(Java高精度)

    题目链接 题意 给出三个圆上的点,和一个目标的点,问目标点是否在这三个点构成的圆外面. 思路 许久没见过的Java高精度,不要加package!!! import java.math.BigDecim ...