Kotlin和Java的回调实现

前言

最近将一些Java代码改成Kotlin代码,在改造过程中经常遇到“事件(函数)”的回调;针对这几种回调的实现,做一次小小的总结;

回调的接口使用Java语言

在Java中我们实现”事件(函数)"的回调,通常使用的是Interface(接口)的方式,基本步骤如下:
调用方:

1.在类中定义一个回调接口;
2.在这个接口中定义回调事件;
3.定义一个拥有执行回调的接口变量;

    public class MyButtonJava {
      public  String mTag = "";
      interface ClickLister {
        void onClickDown(String tag);
      }
      private ClickLister mClickListener  = null;
      void  setListener(ClickLister listener){
        this.mClickListener = listener;
      }
     //在某些业务中进行回调
     void doSomeThing(){
        this.mClickListener.onClickDown(mTag);
     }
 }

被调用方:

1.Java中使用lamda表达式方式调用

MyButtonJava myButton = new MyButtonJava();
myButton.mTag = this.getClass().getName();
myButton.setListener(tag -> ToastUtils.showToast(tag));
myButton.doSomeThing();

但是如果JAVA类中有两个接口,则无法使用lamda表达式

2.Java中使用‘实现接口’的方式调用

MyButtonJavaTwoEvent myButtonTwo = new MyButtonJavaTwoEvent();
myButtonTwo.mTag = this.getClass().getName();
myButtonTwo.setListener(new MyButtonJavaTwoEvent.ClickLister() {
  @Override
 public void onClickDown(String tag) {
  ToastUtils.showToast(tag);
 }

 @Override
 public void onClickUp(String tag) {
  ToastUtils.showToast(tag);
  }
});
myButtonTwo.doSomething();

3.Kotlin中设置只有一个回调函数的JAVA接口

        val myButtonJava = MyButtonJava()
        myButtonJava.mTag = this.javaClass.name
        myButtonJava.setListener{ tag -> ToastUtils.showToast(tag)}
        myButtonJava.doSomeThing()

3.Kotlin中设置有两个回调函数的JAVA接口

        val myButtonJavaTwo = MyButtonJavaTwoEvent()
        myButtonJavaTwo.setListener(object : MyButtonJavaTwoEvent.ClickLister{
            override fun onClickUp(tag: String?) {
                ToastUtils.showToast(tag)
            }

            override fun onClickDown(tag: String?) {
                ToastUtils.showToast(tag)
            }
        })

回调的接口使用Kotlin语言

如果回调的接口使用Kotlin实现,通常接口的定义可以使用两种方式

1.使用Unit方式实现

class MyButtonKotlinUnit {
    var mTag:String = ""
    private lateinit var mClickListener : (String) -> Unit? //接口可以延时加载
    fun setListener(listener: (String) -> Unit?){
        this.mClickListener = listener
    }
    fun init(){
        this.mClickListener.invoke(mTag)
    }
}

2.使用Interface方式实现

class MyButtonKotlinInterface{
    var mTag = ""
    interface ClickLister {
        fun onClickDown(tag: String)
    }
    private var mClickListener: ClickLister? = null
    fun setListener(listener: ClickLister) {
        this.mClickListener = listener
    }
    fun init() {
        this.mClickListener!!.onClickDown(mTag)
    }
}

这样在设置回调函数时的实现方法有:

1.在JAVA中设置使用Interface方法的接口

        MyButtonKotlinInterface myButtonKotlinInterface = new MyButtonKotlinInterface();
        myButtonKotlinInterface.setListener(tag -> ToastUtils.showToast(tag));

2.在Java文件中不能使用Kotlin的Unit方式回调事件
以下编码在编译期会报错

        MyButtonKotlinUnit myButtonKotlin = new MyButtonKotlinUnit();
        myButtonKotlin.setMTag(this.getClass().getName());
        //编译期报错:错误: 不兼容的类型: lambda 表达式中的返回类型错误 void无法转换为Unit
        //Bad return in type lambda expression : void cannot be converted to Unit
        //myButtonKotlin.setListener(tag -> ToastUtils.showToast(tag));
        //myButtonKotlin.doSomeThing();

3.在kotlin中使用unit方式设置

       val myButtonKotlin = MyButtonKotlinUnit()
        myButtonKotlin.mTag = this.javaClass.name
        myButtonKotlin.setListener { tag -> ToastUtils.showToast(tag) }
        myButtonKotlin.init()

4.在kotlin中设置使用Interface方式实现的回调

        val myButtonKotlinTwo = MyButtonKotlinInterface()
        myButtonKotlinTwo.mTag = this.javaClass.name
        myButtonKotlinTwo.setListener(object:MyButtonKotlinInterface.ClickLister{
            override fun onClickDown(tag: String) {
                ToastUtils.showToast(tag)
            }
        })

你可能感兴趣的:(Kotlin和Java的回调实现)