簡體   English   中英

未解決參考:Kotlin中擴展class的方法

[英]Unresolved reference: method of extended class in Kotlin

我的 class 中有一個變量,它擴展了 BroadcastReceiver並實現了另一種稱為isNetworkAvailable的方法。 當我在 class 中調用該方法時,它可以工作,但是從外部調用時會導致“未解析的引用”。 class 的現有方法也可以訪問。

有任何想法嗎?

class MainActivity : AppCompatActivity() {

    private var connectivityReceiver: BroadcastReceiver = object: BroadcastReceiver(){

        override fun onReceive(context: Context, arg1: Intent) {
            if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
                // ...
            }
        }

        fun isNetworkAvailable(context: Context?): Boolean {
            // ...
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        connectivityReceiver.onReceive() // Accessible if arguments are provided 
        connectivityReceiver.isNetworkAvailable(this@MainActivity) // ERROR: Unresolved reference
    }
}

你是可變的connectivityReceiver的類型是BroadcastReceiver ,它沒有方法isNetworkAvailable 不幸的是,它並不像這樣簡單,因為對於 Kotlin connectivityReceiver接收器只不過是一個BroadcastReceiver

要使您的方法可用,您可以創建特定的 class 而不是匿名的 object。

class MyBroadcaseReceiver : BroadcastReceiver(){

    override fun onReceive(context: Context, arg1: Intent) {
        if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
            // ...
        }
    }

    fun isNetworkAvailable(context: Context?): Boolean {
        // ...
    }
}

然后在活動中使用

private var connectivityReceiver: MyBroadcaseReceiver = MyBroadcaseReceiver()

請注意,如果您執行類似的操作

private var connectivityReceiver: BroadcaseReceiver = MyBroadcaseReceiver()

你最終會遇到同樣的問題,因為connectivityReceiver將是BroadcastReceiver而不是isNetworkAvailable定義 isNetworkAvailable 的地方。


也有可能只刪除顯式類型:

private var connectivityReceiver = object: BroadcastReceiver(){

    override fun onReceive(context: Context, arg1: Intent) {
        if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
            // ...
        }
    }

    fun isNetworkAvailable(context: Context?): Boolean {
        // ...
    }
}

Kotlin 的推論應該可以接那個方法。 我認為這不是一個好方法的原因是因為它只有在你想保持這個 object 表達式私有時才有效 - 請參閱object 表達式

請注意,匿名對象只能在本地和私有聲明中用作類型。 If you use an anonymous object as a return type of a public function or the type of a public property, the actual type of that function or property will be the declared supertype of the anonymous object, or Any if you didn't declare any supertype . 在匿名 object 中添加的成員將無法訪問。

基本上意味着在您的情況下,如果您刪除private成員isNetworkAvailable將無法再訪問。 我相信代碼意味着要改變很多,尤其是像這樣的 class 最終應該 go 到它自己的位置,因為它變得更加復雜並且更容易測試。 這當然只是個人意見。

@Fred 的答案是正確的,這是因為編譯器不知道 BroadcastReceiver 的 function 稱為isNetworkAvailable

Kotlin is strong in type interference, you don't need to specify explicitly that the variable is of type BroadcastReceiver it tells the compiler that the object is of type BroadcastReceiver which does not have any function called isNetworkAvailable() .

只需從變量中刪除顯式類型聲明

private var connectivityReceiver = object: BroadcastReceiver() {...}

Kotlin 將使用其推斷的匿名類型 object 自動分配正確的類型。

暫無
暫無

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

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