1. 程式人生 > >java回撥機制詳解

java回撥機制詳解

原文出自這兒:https://blog.csdn.net/fengye454545/article/details/80198446   為了自己能夠加深理解自己動手敲了一遍,也寫寫,有時間看看。更詳細建議訪問原創博主。

======================================================================================

回撥函式

高大上(裝逼)定義:回撥函式就是一個通過函式指標(或介面)呼叫的函式。即你把函式指標(或介面)作為引數傳遞給另一個函式,當這個指標(或介面)被用來呼叫其所指向的函式時,我們就說這是回撥函式。回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫,用於對該事件或條件進行響應。

通俗化(草根)定義:有個類A,有方法a();另一個類B,方法b();當在A類中呼叫了B類的b()方法,在B()中觸發特定事件或條件後回過來呼叫A類中的某個方法比如a()

 

=================================================

看例子:小明和小李相約一起去吃早飯,但是小李起的有點晚要先洗漱,等小李洗漱完成後,通知小明再一起去吃飯。小明就是類A,小李就是類B。一起去吃飯這個事件就是方法a(),小李去洗漱就是方法b()。

 

小白這樣做(雖然達到了目的,但沒有回撥思想,是A類主動呼叫自己的方法):

小李類:

package test1;

public class Xl1 {
	public void WashFace() {
		System.out.println("小李洗臉中。。。");
	}

}

小明類:

package test1;
public class Xm1 {
	
	public void eatRice() {
		System.out.println("小明叫小李一起去吃飯");
		Xl1 xl=new Xl1();
		xl.WashFace();
//		在小明自己的方法中呼叫,沒有回撥思想,
//		還是小明自己等到小李後主動再叫了一遍去吃飯。
		TogatherEat();
	}
	public void TogatherEat() {
		System.out.println("兩人在食堂吃飯中。。。");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Xm1 xm=new Xm1();
		xm.eatRice();
	}

}

改進一下B類就是回撥函式:

package test1;

public class Xl2 {
	public void WashFace() {
		System.out.println("小李洗臉中。。。");
		
		//這裡是小李去叫小明,實現了回撥A中的方法
		Xm1 xm=new Xm1();
		xm.TogatherEat();
	}

}

============================================================

有點水平的這樣做:通過介面實現同步回撥

 

EatRice介面:

package test2;

public interface EatRice {
	public void eat(String food);
}

A類小明實現EatRice的介面:

package test2;

public class Xm2 implements EatRice{

	@Override
	public void eat(String food) {
		// TODO Auto-generated method stub
		System.out.println("小明小李一起去吃"+food);
	}
	
        //通知小李去吃飯
	public void Call_XL() {
		Xl2 xl=new Xl2();
		xl.WashFace(this, "基圍蝦");
	}

	public static void main(String a[]) {
		Xm2 xm=new Xm2();
		xm.Call_XL();
	}

}

B類小李做完事後 回撥即可

package test2;

public class Xl2 {
	public void WashFace(EatRice er,String food) {
		System.out.println("小李先洗臉!");
		er.eat(food);
	}
}

===============================================================

高手這樣做,這是高手。。這真是高手。。。(非同步回撥機制)

借用高手的原文:

上面講的都是同步回撥,可是事實上,小李要洗漱後才能吃飯,在小李洗漱的時候,小明是要做自己的事情的,比如他在玩手機,這樣子就是非同步回調了。而且我們把程式碼正規化,比如在android點選事件中,你會發現你只要實現View.setOnclickListener(this),即可實現回撥,那麼像這樣子的規範是如何實現的,在這一節裡我將會提到。廢話少說,先上程式碼。

EatRice介面沒有變化,這裡就省去介面程式碼展示
--------------------- 
作者:FYM-WR 
來源:CSDN 
原文:https://blog.csdn.net/fengye454545/article/details/80198446 
版權宣告:本文為博主原創文章,轉載請附上博文連結!

A類小明:

package test3;

public class Xm3 implements EatRice {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Xm3 xm=new Xm3();
		xm.Call_XL();
	}
	
	public void Call_XL() {
		
		Xl3 xl=new Xl3();
		xl.setEatRiceListener(this,"基圍蝦");
	}

	@Override
	public void eat(String food) {
		// TODO Auto-generated method stub
		System.out.println("小李小明一起去吃"+food);
	}

}

B類小李:

package test3;

public class Xl3 {
	public EatRice er;
	
	public void setEatRiceListener(EatRice er, String food) {
		this.er = er;
		WashFace(food);
	   }

	
	public void WashFace(String food) {
		System.out.println("小李要洗臉!\n");
		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					play();
					Thread.sleep(10000);
					System.out.println("十秒後\n");
					er.eat(food);
				}
				catch(InterruptedException e){
					e.printStackTrace();
				}
				
			}
			
		}).start();
		
	}
	
	public void play() {
		System.out.println("小明在玩手機\n");
	}
	
}

總結:更加深入理解力監聽事件的原理,其實像安卓的觸控、按鈕監聽原理類似,以後寫程式碼靈活性可以更高,原創博主好文章,致謝!原創連結:https://blog.csdn.net/fengye454545/article/details/80198446