繁体   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