在JAVA中接口是不可以被实例化的 那么这段代码是如何执行的呢?
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.v("Event", "button --> setOnClickListener --> onClick");
}
});
通过文档我们得知OnClickListener是一个接口
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}
既然接口不可以被实例化,那么这段代码是什么意思呢?是的,就是匿名内部类,下面我们通过源码来分析:
首先查看Button的setOnClickListener方法:
public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
其中mOnClickListener是什么呢?没错,就是一个接口类型的引用public OnClickListener mOnClickListener;
这个函数的参数是一个接口的引用,也就是通过匿名内部类将一个实现了接口方法的对象赋予了这个引用,换句话说就是接口类型的引用指向了实现了接口的对象.这就是传说中Java多态的一种体现之一:接口回调
接口回调:
可以把使用实现了某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调
所有当我们把实现了接口的匿名对象传递过去,这时候调用setOnClickListener时,就会回调到我们实现的方法OnClick.从而实现了通过接口调用方法,来屏蔽具体的实现方法.为模板提供了方便,使其不用关心具体的实现.