假设我有一个Callbacks
界面,其中有两种方法onCurrentLocation
和onError
:
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
的空检查,因为它与问题无关。
答案 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
}
}