需求
需要外部類代爲實現類本身實現不了的某個功能,並能讓返回值在類內部進行處理。
基礎部分
分析
將使用情況拆開來,分爲以下幾點:
- 需要外部類代爲實現
- 返回值由類自行處理
需要滿足以上兩個功能,必須的條件爲:
- 類中需要有方法來調用外部的類的方法
- 需要創建一個方法來處理外部的類返回的數據
- 爲了讓外部的類內調用到處理數據的方法,則需要將實例化好的對象傳遞給外部的類。
邏輯圖
代碼
結構圖
class A
package callbackdemo;
public class A {
/**
* 調用B中的方法
* @param str
*/
public void methodA(){
B b = new B();
System.out.println("調用了A類中的A方法");
// 調用B的方法A的同時,將對象本身傳遞給B
b.methodA(this);
}
public void methodB(){
System.out.println("調用了A類中的B方法");
}
}
class B
package callbackdemo;
public class B {
public void methodA(A a) {
System.out.println("調用了B中的A方法");
// A方法中對對象A的B方法進行了調用(這個步驟就是回調)
a.methodB();
}
}
測試
測試代碼
package callbackdemo;
public class T {
public static void main(String[] args) {
A a = new A();
a.methodA();
}
}
運行結果
拓展部分
分析
上述代碼中存在以下兩個問題:
- 耦合性太強,不好複用
- 如果B需要持續調用回調函數的話,一段時間之後就會無法調用
解決方式:
- 使用接口來解耦合
- 將回調方法寫成靜態內部類的形式,使B方法可以持續得調用
邏輯圖
代碼
結構圖
interface CallBack
package callbackdemo;
public interface CallBack {
public void invoke();
}
class A
package callbackdemo;
public class A {
public static ACallBack ac;
/**
* 調用B中的方法
* @param str
*/
public void methodA(){
B b = new B();
System.out.println("調用了A類中的A方法");
ac = new ACallBack();
b.methodA(ac);
}
public static class ACallBack implements CallBack{
@Override
public void invoke() {
System.out.println("調用了A類中回調類的invoke方法");
}
}
}
class B
package callbackdemo;
import callbackdemo.A.ACallBack;
public class B {
public void methodA(ACallBack ac) {
System.out.println("調用了B中的A方法");
ac.invoke();
}
}
測試
測試代碼
package callbackdemo;
public class T {
public static void main(String[] args) {
A a = new A();
a.methodA();
}
}
運行結果
另
改造之後,若有class C需要調用B中的方法Method A,則可以參照以下邏輯圖來實現