/**//*引用外圍類對象:在外圍類名稱後面跟一個句點和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類.
*回調的價值在於它的靈活性,可以在運行時動態地決定需要調用什麼方法.
*/