Можно ли изменить тип получателя свойств Kotlin? - PullRequest
0 голосов
/ 28 ноября 2018

Возможно ли преобразовать свойства типа получателя?

Например, внутри объявления класса у меня есть val member = Implementation(), но я хочу, чтобы получатель public возвратил ссылку, набранную с помощью SomeInterface при условии, что Implementation является подтипом SomeInterface, тогда как в объявлении класса этот тип будет использоваться как экземпляр Implementation.

Вот полный пример на Java, чтобы дать ясную картину:

public class MyViewModel extends ViewModel {
    private final MutableLiveData<Settings> settings = new MutableLiveData<>();

    public LiveData<Settings> getSettings() {
        return settings;
    }

    public void updateSettings() {
        settings.setValue(new Settings());
    }
}

Здесь это «свойство» видимо снаружи как LiveData (супертип MutableLiveData), но внутри класса его можно использовать как MutableLiveData.

Я бы сказал, это звучит нормально, но кажется, что Котлин этого не допускает.Я что-то пропустил?Или создание private val _private = Implementation() и val _public: SomeInterface = _private или реализация пользовательского метода с семантикой получателя и измененным именем, имеющим SomeInterface тип возвращаемого значения - единственный способ достичь этого?

1 Ответ

0 голосов
/ 28 ноября 2018

Я думаю (если я правильно понял ваш вопрос), что явное объявление типа member будет делать то, что вы хотите, например,

interface SomeInterface

class Implementation : SomeInterface

class Test {
    val member: SomeInterface = Implementation()
}

ОБНОВЛЕНИЕ : после вопросаобновлен, чтобы уточнить, что в классе Test member должен иметь тип Implementation, а не SomeInterface ...

Я не думаю, что то, что вы пытаетесь сделать, может быть сделано безпеременная-член, как вы предлагаете в своем вопросе.Однако, если у вас есть базовый класс, который определяет, каким должен быть member, вы можете делать то, что вы хотите:

interface SomeInterface

class Implementation : SomeInterface

abstract class Super {
    abstract val member: SomeInterface
}

class Test : Super() {
    override val member = Implementation()  
    // declared as Implementation, but does correctly implement superclass which wants this to be a SomeInterface.
    // In this class, member is of type Implementation.
}

fun test() {
    val test1 = Test()
    val member1 = test1.member  // member1 is an Implementation object

    val test2: Super = Test()
    val member2 = test2.member  // member2 is a SomeInterface object
}

То, что показано выше, это то, что вы можете иметьmember, который доступен в вашем классе как Implementation, но виден за пределами класса как SomeInterface.Но только если, когда вы работаете с ним вне класса, вы работаете с ним как с экземпляром суперкласса, который определяет member как тип SomeInterface.

...