[Java]什么是接⼝回调?
1.接⼝回调是什么[2]?
接⼝回调是指:可以把使⽤某⼀接⼝的类创建的对象的引⽤赋给该接⼝声明的接⼝变量,那么该接⼝变量就可以调⽤被类实现的接⼝的⽅法。实际上,当接⼝变量调⽤被类实现的接⼝中的⽅法时,就是通知相应的对象调⽤接⼝的⽅法,这⼀过程称为对象功能的接⼝回调。看下⾯⽰例。
interface People{
void peopleList();
}
class Student implements People{
public void peopleList(){
System.out.println("I’m a student.");
}
}
class Teacher implements People{
public void peopleList(){
System.out.println("I’m a teacher.");
}
}
public class Example{
public static void main(String args[]){
People a; //声明接⼝变量
a=new Student(); //实例化,接⼝变量中存放对象的引⽤
a.peopleList(); //接⼝回调
a=new Teacher(); //实例化,接⼝变量中存放对象的引⽤
a.peopleList(); //接⼝回调
}
}
结果:
I’m a student.
I’m a teacher.
再来看看向上转型(upcasting)的概念。
2.什么是向上转型[1]?
Shape s=new Circle();
这⾥,创建了⼀个Circle对象,并把得到的引⽤⽴即赋值给Shape。通过继承,Circle就是⼀种Shape。
假设你调⽤基类⽅法(它已在导出类中被覆盖):
s.draw();
由于后期绑定(多态),将会正确调⽤Circle.draw()⽅法。
3.向上转型与接⼝回调的区别
看似向上转型和接⼝回调是⼀回事。看下⾯两句话,均出⾃Thinking in Java。
使⽤接⼝的核⼼原因:为了能够向上转型为多个基类型[1]。即利⽤接⼝的多实现,可向上转型为多个接⼝基类型(具体见《抽象与接⼝》章节6)。
从实现了某接⼝的对象,得到对此接⼝的引⽤,与向上转型为这个对象的基类,实质上效果是⼀样的。(此句摘⾃Thinking in Java 3rd 接⼝与内部类⼀章)
所以,我认为,这两个概念是从两个⽅⾯来解释⼀个⾏为。接⼝回调的概念,强调使⽤接⼝来实现回调对象⽅法使⽤权的功能(下⼀章节详细分析)。⽽向上转型则牵涉到多态和运⾏期绑定的范畴。
4.⽤ Java 接⼝实现回调函数的等价功能
熟悉 MS-Windows 和 X Window System 事件驱动编程模型的开发⼈员,习惯于传递在某种事件发⽣时调⽤(即“回调”)的函数指针。Java 的⾯向对象模型⽬前并不⽀持⽅法指针,Java 的接⼝⽀持提供了⼀种获得回调的等价功能的机制。其技巧就是:定义⼀个简单接⼝,并在该接⼝中声明我们要调⽤的⽅法。
假定我们希望在某个事件发⽣时得到通知。我们可以定义⼀个接⼝:
InterestingEvent.java
package org.zj.sample;
public interface InterestingEvent {
public void interestingEvent ();
}
这使得我们可以控制实现该接⼝的类的任何对象。因此,我们不必关⼼任何外部类型信息。
发出事件信号的类必须等待实现了 InterestingEvent 接⼝的对象,并在适当时候调⽤ interestingEvent() ⽅法。
EventNotifier.java
package org.zj.sample;
public class EventNotifier {
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier(InterestingEvent event) {
ie = event; // 保存事件对象以备后⽤。
somethingHappened = false; // 还没有要报告的事件。
}
public void doWork() {
if (somethingHappened) { // 检查设置的谓词。
ie.interestingEvent();// 通过调⽤接⼝的这个⽅法发出事件信号。
}
}
public void setHappened(){//设置谓词。
somethingHappened=true;
}
}
在上例中,使⽤ somethingHappened 谓词来跟踪是否应触发事件。希望接收事件通知的代码必须实现 InterestingEvent 接⼝,并将⾃⾝引⽤传递给事件通知程序。
CallMe.java
package org.zj.sample;
public class CallMe implements InterestingEvent {
@SuppressWarnings("unused")
private EventNotifier en;
public CallMe() {
// 注意 EventNotifier (InterestingEvent event),应该传递⼀个接⼝类型。
// ⽽下⾯将 this,即实现了 InterestingEvent接⼝的 CallMe实例传递给
//EventNotifier。也就是所谓的接⼝回调了。
en = new EventNotifier(this); // 创建事件通知程序,并将⾃⾝引⽤传递给它。
}
// 为事件定义实际的处理程序。
public void interestingEvent() {
System.out.println("Call me Hello.");
}
}
下⾯写个测试类。
Test.java
package org.zj.sample;
public class Test {
public static void main(String[] args) {
EventNotifier en=new EventNotifier(new CallMe());
en.setHappened();
en.doWork();
}
}
结果:
java接口可以创建对象吗Call me Hello.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论