Java-InnerClass-06

/*引用外围类对象:在外围类名称后面跟一个句点和this关键字来实现.eg:在类Sequence.SSelector中,通过Sequence.this,内部类任何方法都能获取那个指向外围类Sequence的被保存的引用.
 *对象要想生成其自身内的内部类的对象,必须在new中提供一个引用,指向那个外围类对象.eg:Contents con = parcel.new Contents();等效于Contents con = parcel.getContents();
 *创建内部类对象,不能想当然地认为只需加上外围类Parcel的名字就ok了,而是必须使用此外围类的对象来创建其内部类的对象.这是因为此内部类的对象会消消地连接到创建它的外围类的对象(当然嵌套类例外).
 
*/


/*为什么需要内部类?
 *内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类对象.所以可以认为内部类提供了某种进入其外围类的窗口.
 *用外围类实现某个接口不是总能享用到接口带来的方便(否则内部类就没有必要存在了),所以内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响.
 *内部类提供了继承多个类(非abstract的或abstract的)的能力(内部类允许继承多个非接口类型),所以说内部类使得多重继承的解决方案更加完整(外围类只能继承多个接口和一个超类).
 *
 *对于多个接口:当遇到问题的时候,通常问题本身就能给出某些指引,告诉你是应该使用单一类还是内部类;
 *对于多个基类:只能使用内部类才能实现多重继承.
 
*/


/*闭包与回调
 *闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域.通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有成员(包括private成员).
 *回调(callback):通过回调,对象能够携带一些信息,这些信息允许它在稍后的某个时刻调用初始的对象.
 *通过内部类提供闭包的功能是完美的解决方案.
 
*/

interface MyIncrement1{void increment();}
class MyIncrement2{
    
void increment(){System.out.println("class MyIncrement's operation: increment()");}
    
static void f(MyIncrement2 mi){mi.increment();}
}


class callee1 implements MyIncrement1{
    
private int i;
    
public void increment(){
        System.out.println(
"callee1:interface MyIncrement1's operation: increment() " + (i++));
    }

}

class callee2 extends MyIncrement2{
    
private int i;
    
private void incr(){System.out.println("callee2:interface MyIncrement1's operation: increment() " + (i++));}
    
private class closure implements MyIncrement1{
        
public void increment(){incr();}
    }

    
public MyIncrement1 getCallbackReference(){return new closure();}
}

class caller{
    
private MyIncrement1 callbackReference;
    caller(MyIncrement1 mi)
{callbackReference = mi;}
    
void go(){callbackReference.increment();}
}

class Callbacks{
    
public static void main(String[] args) {
        callee1 c1 
= new callee1();
        callee2 c2 
= new callee2();
        MyIncrement2.f(c2);
        caller caller1 
= new caller(c1);
        caller caller2 
= new caller(c2.getCallbackReference());
        caller1.go();
        caller2.go();
        caller1.go();
        caller2.go();
    }

}


/*上例进一步揭示了外围类实现一个接口和内部类实现此接口的区别.callee1是简单的继承接口,callee2继承自MyIncrement2,而类MyIncrement2已经有了一个increment()方法,并且与MyIncrement1接口中的increment()方法完全不相关.
 *所以如果callee2继承了MyIncrement2,就不能为了MyIncrement1的用途而覆盖MyIncrement2的increment()方法.于是只能使用内部类独立地实现MyIncrement1.
 *在callee2中除了getCallbackReference()以外,其他成员都是private的.要想建立与外部世界的任何连接,接口MyIncrement1是必需的.
 *内部类Closure实现了MyIncrement1,以提供一个返回callee2的"钩子"(而且是个安全的钩子).无论谁获得此MyIncrement1的引用,都只能调用increment()方法,除此之外没有其他功能.
 *caller构造器需要一个MyIncrement1的引用作为参数,然后在以后的某个时刻,caller对象可以使用此引用回调callee类.
 *回调的价值在于它的灵活性,可以在运行时动态地决定需要调用什么方法.
 
*/
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值