覆盖Kotlin lambda表达式中的多个接口方法

时间:2017-10-02 22:59:56

标签: android lambda interface kotlin

假设我有一个Callbacks界面,其中有两种方法onCurrentLocationonError

    public interface Callbacks {

        void onCurrentLocation(ClientLocation location);

        void onError();
    }

和一个在其构造函数中使用此接口的类,例如:

public MyLocationClient(Callbacks callbacks) {...}

现在,在Kotlin中,我是否应该能够以这种方式实例化MyLocationClient:

val myLocationClient = MyLocationClient(
                    { location: ClientLocation ->
                          updateClientLocation(location)
                    },
                    {})

如果没有,为什么不呢?

我所看到的行为是:当界面只有一个方法时,这个对象的构造编译得很好。但是,只要我向Callbacks添加更多方法,编译器就会抱怨

  

"类型不匹配。必需:回调!找到:(ClientLocation) - >   单元"

编辑:删除location的空检查,因为它与问题无关。

5 个答案:

答案 0 :(得分:4)

所以你要在匿名类上创建一个不是函数接口的实例(它们只有一个方法),所以它会是这样的:

val myLocationClient = MyLocationClient(object : Callbacks {

        override fun onCurrentLocation(location : ClientLocation?){
            location?.let{ updateLocation(it) }
        }

        override fun onError(){ // should you not handle errors? }
    })

答案 1 :(得分:0)

我想这是一件好事,它不起作用,因为当接口有两个相同类型的函数时,你做了什么?

public interface Callbacks {
    void anotherFunction(ClientLocation location);

    void onCurrentLocation(ClientLocation location);
}

因此,将此限制为SAM(单一抽象方法)接口是一种很好的方法。

答案 2 :(得分:0)

您可以定义

class CallbacksImpl(private val onCurrentLocationF: (ClientLocation) -> Unit, private val onErrorF: () -> Unit) : Callbacks {
  override fun onCurrentLocation(location : ClientLocation) { onCurrentLocationF(location) }

  override fun onError() { onErrorF() }
}

并使用它

MyLocationClient(CallbacksImpl(
    { location -> updateClientLocation(location) },
    {}))

它仍然有一些样板,但每次使用一次而不是每次使用一次,因此它很容易成为一个很好的权衡。

答案 3 :(得分:0)

interface IAnimatedRatingBar {
   fun setProgressImageResource(resourceId: Int)


   fun setProgressImageDrawable(drawable: Drawable)


   fun setSecondaryProgressImageResource(resourceId: Int)


   fun setSecondaryProgressImageDrawable(drawable: Drawable)

   fun startAnimate()
}

这对我来说很好。

答案 4 :(得分:0)

您可以使用 Kotlin 的高阶函数并合并接口检查此示例的两种方法

import android.location.Location

interface Callbacks {

 fun onCurrentLocation(location: Location)
 
 fun onError()

}

现在定义一个实现回调接口的类

import android.location.Location

class MyLocationClient(private val callbackListener: (isSuccess:Boolean, location: Location?, error:String) -> Unit): Callbacks {

override fun onCurrentLocation(location: Location) {
    callbackListener(true,location, "No Error")
}

override fun onError() {
    callbackListener(false,null, "Unable to get location")
}

}

随心所欲地使用它

val myLocationClient = MyLocationClient { isSuccess, location, error ->
        if (isSuccess){
            // proceed with location
        }else{
            // error occured show it to user
        }
    }