java基礎-------閉包和回撥
閉包是一種能被呼叫的物件,它儲存了建立它的作用域資訊,java7中沒有顯示的支援閉包,但對於非靜態的內部類而言,它不僅記錄了其外部類的資訊,還保留了一個建立非靜態內部類物件的引用,並且可以直接回調外部類的private成員因此可以把非靜態的內部類面向物件因此可以把非靜態的內部類當成面向物件領域的閉包。
通過這種仿閉包的非靜態的內部類可以實現回撥,回撥就是某個方法獲得內部類的物件的引用後,就可以在合適的時候反過來去呼叫外部類的例項的方法,簡單的說所謂回撥就是允許客戶類通過內部類的引用呼叫外部類的方法。
example:
下面定義了一個Teachable介面和Programmer基類,它們都提供了work方法 它們的方法簽名完全一樣但是功能是不一樣的:
public interface Teachable {
void work();
}
public class Programmer {
private String name;
public Programmer()
{}
public Programmer(String name)
{
this.name=name;
}
public void work()
{
System.out.println("我是programmer。。。。。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
假若在現實的生活當中存在這樣人既是程式設計師也是講師,就像黑馬的好多老師,嘿嘿,也就是說要定義一個特殊的類,該類既要是實現Teachable介面也需要繼承Programmer類表面上看沒有任何問題,問題是該介面和類裡定義了相同的work方法如果採用如下的程式碼定義一個特殊的TeachableProgrammer類
public class TeachableProgrammer extends Programmer implements Teachable
{
public work()
{
System.out.println(getName+"我在上課。。。");
}
}
顯然上面的TeachableProgrammer類只有一個work()方法,這個work()方法只能進行教學的作用不可以進行程式設計的功能但實際上我們是既要教學的功能也要程式設計的功能的這個時候 解決的辦法的就是可以用仿閉包的內部類來實現
public class Teacher_Programmer extends Programmer
{
public Teacher_Programmer()
{}
public Teacher_Programmer(String name)
{
super(name);
}
//隱藏細節
private void teach()
{
System.out.println(getName+"我在上課。。。");
}
//隱藏細節
private class Closure implements Teachable
{
@Override
public void work() {
// TODO Auto-generated method stub
teach();
}
}
public Teachable getTeachable()
{
return new Closure();
}
}
上面的TeachableProgrammer類只是Programmer的子類它可以直接的繼承父類的方法,該類直接的涵蓋了程式設計的方法的功能,與上面定義的介面沒有關係,它也不能當成Teachable介面來使用,此時建立了一個Closure內部類它實現了Teachable介面並且是實現了work的方法體但是這種實現是通過回撥外部類中定義的teach方法來實現的。如果要實現外部類的物件具有教學的功能只需要內部類呼叫外部類定義的教學方法work即可,那這裡就就自然涉及到要獲得內部類的引用的方法了所以定義了getTeachable()方法這就是所謂的獲得內部類的引用進而回調外部類的方法也就是開頭講到的閉包回撥。
函式的入口:
public class MainClass {
/**
* @param args
*/
public static void main(String []args)
{
Teacher_Programmer t_p=new Teacher_Programmer("wangyong");
t_p.work();
t_p.getTeachable().work();
}
}