我曾经使用 Java 进行开发,直到我开始使用 C# 及其委托进行编程时,我才完全理解回调的概念。
这是因为@Denilson Sá 完美地提到 Java 不使用指向函数的指针。
换句话说,在 Java 中,您可以调用方法并传递一些参数,例如原始值(int、long、char、boolean 等)和对象(字符串或任何类的任何实例,因为当您传递对象时,您基本上是传递位于内存某处的真实对象在内存中的地址)。
Java 中的回调概念可以通过使用接口并将它们(实现它们的对象)作为参数传递来实现。想象一下,您有以下接口,它定义了 2 个方法,任何想要充当 ResultListener 的类都必须实现这些方法。
interface ResultListener {
void onSuccessOperation(String description);
void onFailedOperation(String description);
}
现在假设您有一个在 showScreen 方法中运行的主程序
class MyMainScreen implements ResultListener {
public void showScreen() {
//do some things..
SmartClass smartClass = new SmartClass();
smartClass.divideAndNotify(5, 0, this);
}
public void onSuccessOperation(String description) {
System.out.println("SUCCESS!!. " + description);
}
public void onFailedOperation(String description) {
System.out.println("FAILED. " + description);
}
}
这就是知道如何划分的 SmartClass。
class SmartClass {
public void divideAndNotify(int numerador, int denominador, ResultListener resultListener) {
if (denominador == 0) {
resultListener.onFailedOperation("Nobody can divide by zero!!");
} else {
int total = numerador / denominador;
resultListener.onSuccessOperation("The result is " + total);
}
}
}
这里有趣的部分是 MyMainScreen 的行为类似于 ResultListener,因此它需要实现接口 ResultListener 中定义的方法。
MyMainScreen 知道如何在控制台上打印消息,但它对计算一无所知,这就是为什么它实例化 SmartClass 以使用它的方法 divideAndNotify 接受 2 个数字和对将侦听结果的实例的引用(在我们的如果这个实例是 MyMainScreen 实例本身,这就是为什么它用词 this)
传递自己
SmartClass 方法 divideAndNotify 知道数学,并会通知正在监听的人操作结果。它的方法知道 resultListener 将包含对一个对象的引用,该对象知道当结果成功或不成功时该做什么。
这里的回调概念是 SmartClass 将功能委托给如何处理结果,就像“回调”它作为参数接收的实例中的某些内容。
总而言之:回调只是一个任务的委托。
PS:对于 C#,这个概念要简单得多,因为 C# 具有委托类型,这些委托类型是存储函数所在内存地址的变量(存储的函数必须与委托中定义的签名匹配)。