简体   繁体   English

未解决参考:Kotlin中扩展class的方法

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

I have a variable in my class that extends BroadcastReceiver and implements one additional method called isNetworkAvailable .我的 class 中有一个变量,它扩展了 BroadcastReceiver并实现了另一种称为isNetworkAvailable的方法。 When I call the method within the class it works but it results in "Unresolved reference" when called from outside.当我在 class 中调用该方法时,它可以工作,但是从外部调用时会导致“未解析的引用”。 The preexisting methods of the class are also accessible. class 的现有方法也可以访问。

Any ideas?有任何想法吗?

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
    }
}

You're variable connectivityReceiver is of type BroadcastReceiver , which has no method isNetworkAvailable .你是可变的connectivityReceiver的类型是BroadcastReceiver ,它没有方法isNetworkAvailable Unfortunately, it's not as simple as this because for Kotlin connectivityReceiver is nothing but a BroadcastReceiver .不幸的是,它并不像这样简单,因为对于 Kotlin connectivityReceiver接收器只不过是一个BroadcastReceiver

To make your method available you can create a specific class and not an anonymous object.要使您的方法可用,您可以创建特定的 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 {
        // ...
    }
}

Then in the activity just use然后在活动中使用

private var connectivityReceiver: MyBroadcaseReceiver = MyBroadcaseReceiver()

Note that if you do something like请注意,如果您执行类似的操作

private var connectivityReceiver: BroadcaseReceiver = MyBroadcaseReceiver()

you'll end up in the same issue since connectivityReceiver will be a BroadcastReceiver and not the class where isNetworkAvailable is defined.你最终会遇到同样的问题,因为connectivityReceiver将是BroadcastReceiver而不是isNetworkAvailable定义 isNetworkAvailable 的地方。


There's also the possibility of just removing the explicit type:也有可能只删除显式类型:

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's inference should be able to pick up the method then. Kotlin 的推论应该可以接那个方法。 The reason why I think this is not a great approach is because it only works if you want to keep this object expression private - see object expressions我认为这不是一个好方法的原因是因为它只有在你想保持这个 object 表达式私有时才有效 - 请参阅object 表达式

Note that anonymous objects can be used as types only in local and private declarations.请注意,匿名对象只能在本地和私有声明中用作类型。 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. 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 . Members added in the anonymous object will not be accessible.在匿名 object 中添加的成员将无法访问。

Basically means in your case if you remove private the member isNetworkAvailable won't be accessible anymore.基本上意味着在您的情况下,如果您删除private成员isNetworkAvailable将无法再访问。 I believe code is meant to change a lot and especially a class like that eventually should go to its own place as it becomes more complex and makes it easier to test.我相信代码意味着要改变很多,尤其是像这样的 class 最终应该 go 到它自己的位置,因为它变得更加复杂并且更容易测试。 This is of course just a personal opinion.这当然只是个人意见。

@Fred answer is correct, it is because compiler don't know that the BroadcastReceiver has the function called isNetworkAvailable . @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() . 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() .

Just remove the explicit type declaration from the variable只需从变量中删除显式类型声明

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

Kotlin will automatically assign the correct type using its inferred type of anonymous object. Kotlin 将使用其推断的匿名类型 object 自动分配正确的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM