回調是實現「好萊塢原則」的核心手段:**Don't call us, we'll call you**。本文通過「小明做數學題」的漸進式故事,層層遞進講解同步調用 → 委託調用 → 回調接口 → 多態擴展的完整演進邏輯。
小明自己心算 1+1=2,Student.fillBlank() 內部直接調用 calcADD()。調用鏈:Test → Student → calcADD,全程同步阻塞。
題目變難 168+291,小明借用 Calculator.add()。調用鏈:Student → Calculator,控制權仍在 Student,計算完直接返回繼續執行。
題目更難 26549+16487,小明找小紅幫忙並**出去玩**。關鍵代碼:
// 超級計算器(小紅+計算器)
public class SuperCalculator {
public void add(int a, int b, Student xiaoming) {
int result = a + b;
xiaoming.fillBlank(a, b, result); // 回調:調用傳入對象的方法
}
}
// 小明
public void callHelp(int a, int b) {
new SuperCalculator().add(a, b, this); // 傳入自身引用
}
public void fillBlank(int a, int b, int result) { // 回調函數
System.out.println(name + "求助小紅計算:" + a + " + " + b + " = " + result);
}
執行流:Student.callHelp → SuperCalculator.add → 計算 → Student.fillBlank(回調)。小明無需等待計算完成,實現異步非阻塞。
老婆婆也要用小紅算賬,但不是 Student。引入接口 doJob 統一協議:
public interface doJob { void fillBlank(int a, int b, int result); }
// SuperCalculator 依賴接口而非具體類
public void add(int a, int b, doJob customer) { ... }
// Student 內部類實現接口
public class doHomeWork implements doJob { ... }
public void callHelp(int a, int b) { new SuperCalculator().add(a, b, new doHomeWork()); }
// Seller 同樣實現接口
public class doHomeWork implements doJob { ... }
至此形成經典回調模式:**調用方實現接口 → 傳入被調用方 → 被調用方完成任務後調用接口方法**。
calc.add(a, b, (x,y,r) -> System.out.println(r))