Интерфейс как собственность в Котлине - PullRequest
0 голосов
/ 01 апреля 2019

В некоторых фрагментах и ​​других классах (в Java) у меня есть public interface ISomeActions с функциями, которые я затем вызываю из некоторых других частей этого класса для обозначения действий.Итак, у меня есть ISomeListener listener, который я установил в конструкторе, или сразу после создания объекта SomeClass.Как я могу добиться этого в Kotlin?

Пример:

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

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

Я думаю, что могу использовать lateinit var listener : SomeListener, но я не знаю, будет ли этого достаточно.Член является интерфейсом, а не реализацией этого интерфейса, если он вызывается после завершения действия.

1 Ответ

0 голосов
/ 01 апреля 2019

1) Конструктор

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

Таким образом, myInterface является неизменным. Вы можете быть уверены, что это никогда не будет нулевым.

2) После создания объекта - null

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

Теперь myInterface является изменяемым и может быть нулевым в любое время. Вы можете безопасно получить к нему доступ через myInterface?.someMethod() (если myInterface - нулевой вызов не будет вызван). Для доступа и назначения слушателя используйте 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 предназначен для введения поля после создания, для DI-фреймворков, таких как dagger. Если вы попытаетесь вызвать метод на myInterface, если он еще не инициализирован, UninitializedPropertyAccessException будет брошено. Вы можете проверить, инициализировано ли свойство так:

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

По-моему, вы должны использовать первый или второй подход. Как я понимаю, вы не всегда можете инициировать объект с экземпляром MyInterface, поэтому второй вариант кажется правильным для ваших целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...