簡體   English   中英

在 Kotlin lambda 表達式中覆蓋多個接口方法

[英]Overriding multiple interface methods in Kotlin lambda expressions

假設我有一個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的空檢查,因為它與問題無關。

所以你在一個匿名類上創建一個實例,它不是一個功能接口(他們只有一個方法)所以它會是這樣的:

val myLocationClient = MyLocationClient(object : Callbacks {

        override fun onCurrentLocation(location : ClientLocation?){
            location?.run{ updateLocation(this) }
        }

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

你可以定義

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) },
    {}))

它仍然有一些樣板文件,但每個接口一次而不是每次使用一次,因此它很容易成為一個很好的權衡。

我想這是一件好事,它不起作用,因為當接口有兩個相同類型的功能時,你會怎么做?

public interface Callbacks {
    void anotherFunction(ClientLocation location);

    void onCurrentLocation(ClientLocation location);
}

因此,將其限制為 SAM(單一抽象方法)接口是我想說的一種好方法。

interface IAnimatedRatingBar {
   fun setProgressImageResource(resourceId: Int)


   fun setProgressImageDrawable(drawable: Drawable)


   fun setSecondaryProgressImageResource(resourceId: Int)


   fun setSecondaryProgressImageDrawable(drawable: Drawable)

   fun startAnimate()
}

這對我來說很好用。

您可以使用 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
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM