首页 > 解决方案 > 接口作为 Kotlin 中的属性

问题描述

在某些 Fragments 和其他类(在 Java 中)中,我有一个public interface ISomeActionswith 函数,然后我从该类的其他部分调用这些函数来表示操作。所以,我有一个ISomeListener listener我在构造函数中设置的,或者在我创建一个SomeClass. 我怎样才能在 Kotlin 中实现这一点?

例子:

public class SomeClass{
    public ISomeListener listener;
    public interface ISomeListener{
       public void doSomething();
    }

    void actuallyDoSomething(){
        listener.doSomething();
    }
}

我想我可以使用 a lateinit var listener : SomeListener,但我不知道这是否足够。该成员是一个接口,而不是该接口的实现,以防在 Activity 完成后调用它。

标签: androidkotlin

解决方案


1) 构造函数

class MyClass(private val myInterface: MyInterface) { ... }

这种方式myInterface是不可变的。您可以确定这永远不会为空。

2)对象创建后 -null

class MyClass(var myInterface: MyInterface? = null) { ... }

NowmyInterface是可变的,可以随时为空。您可以通过安全访问它myInterface?.someMethod()(is myInterfaceis null 调用不会被调用)。要访问和分配侦听器,请使用myClassInstance.myInterface = myInterfaceInstance.

由于默认参数,您可以使用或不使用构造函数参数创建您的类:

val myClass1 = MyClass()
val myClass2 = MyClass(interfaceInstanceOrNull)

3)对象创建后 -lateinit

class MyClass(myInterface: MyInterface? = null) {
    lateinit var _myInterface: MyInterface
    init {
        if (myInterface != null) { _myInterface = myInterface }
    }
}

在我看来,最糟糕的解决方案。lateinit专为创建后注入字段而设计,适用于dagger等DI框架。如果您尝试调用方法,myInterface如果它尚未初始化,UninitializedPropertyAccessException则会被抛出。您可以检查属性是否像这样初始化:

if (::_myProperty.isInitialized) { _myProperty.doSth() }

我认为您应该使用第一种或第二种方法。据我了解,您不能总是使用 MyInterface 实例来初始化对象,因此第二个对于您的目的来说似乎是合法的。


推荐阅读