Java编程思想:为什么要使用内部类

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();
    }
}

猜你喜欢

转载自www.cnblogs.com/junjie2019/p/10545905.html