Java是一门面向对象语言,一切皆对象,因此在Java中不存在回调函数这一说法的。由于Java的一切皆对象性质,从而将回调函数这个特性提升到了接口回调。

接口回调是什么?

接口回调:可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。

从概念可以看出,接口回调是指一个使用过程,并强调是关于对象功能的使用过程,既然是功能,功能一般就对应着方法体(函数),因此它同样满足与回调函数相似的模型。

(1)接口的定义(里面有方法)

(2)接口的实现 (类去实现这个接口)

(3)调用接口 

将(2)的引用(地址)传递给(3),然后(3)调用(2)中的方法,这一过程称为对象功能的接口回调。

如何使用接口回调?

接口回调,我将其分为两种方式,一种推模式,一种为拉模式。

推模式

接口回调的推模式,指的是,甲方主动将其地址推送给调用者。比如下例:

接口:


public interface GasListener
{
    public void offerGas(String msg);
}


public class GasCompany implements GasListener
{    
    public void advertiseTo(IndoorsMan man)
    {
        System.out.println("煤气公司:这是我们的联系方式,欢迎来电!");
        man.setListener(this);
    }
    @Override
    public void offerGas(String msg)
    {
        System.out.println("煤气公司接收的订单:"+msg);
    }
}

调用者: 



public class IndoorsMan 
{
    GasListener gListener;
    public void prepareCook()
    {
        System.out.println("宅男:准备下厨做几个花式大菜!");
        System.out.println("宅男:进厨房,烧菜...");
        System.out.println("宅男:刚开火,就发现煤气不足,没办法,只能打电话叫煤气。");
        gListener.offerGas("宅男:送一瓶煤气过来!");
    }    
    public void setListener(GasListener gListener)
    {
        this.gListener = gListener;
    }
}

测试: 



public class Test
{
    public static void main(String[] args)
    {
        IndoorsMan man = new IndoorsMan();
        GasCompany company = new GasCompany();
        
        company.advertiseTo(man);
        man.prepareCook();
    }            
}

GasCompany公司在打广告时,就主动把自身信息告诉了IndoorsMan,当IndoorsMan发现煤气不足这一事件发生时,IndoorsMan就根据接口的引用调用GasCompany服务。 



拉模式


接口回调的拉模式,指的是,调用者自己主动获取甲方的信息。


调用者


public class IndoorsMan 
{
    GasListener gListener;
    public void prepareCook()
    {
        System.out.println("宅男:准备下厨做几个花式大菜!");
        System.out.println("宅男:进厨房,烧菜...");
        System.out.println("宅男:刚开火,就发现煤气不足,没办法,只能打电话叫煤气。");
        gListener.offerGas("宅男:送一瓶煤气过来!");
    }    
    public void setListener(GasListener gListener)
    {
        this.gListener = gListener;
    }
    public void configureGas()
    {
        // 主动获取甲方信息
        setListener(new GasListener()
        {            
            @Override
            public void offerGas(String msg)
            {
                System.out.println("下单内容:"+msg);
            }
        });
    }    
}


测试


public class Test
{
    public static void main(String[] args)
    {
        IndoorsMan man = new IndoorsMan();
        man.configureGas();
        man.prepareCook();
    }            
}


再比如,使用线程Thread时,常常会在构建线程对象时,主动获取Runnable接口的实现。


public class Test
{
    public static void main(String[] args)
    {
        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
            
            }
        });
    }            
}


 


扩展:


接口回调机制满足观察者设计模式,观察者将自身地址注册给被观察者,当某一事件发生时,被观察者根据注册的地址调用相应的观察者。