可以更改Kotlin的属性获取器类型吗?

时间:2018-11-28 11:38:48

标签: kotlin properties getter upcasting

是否可以向上转换属性获取器类型?

例如,在类声明中,我有val member = Implementation(),但我想让 public getter返回一个用SomeInterface输入的引用,假设ImplementationSomeInterface的子类型,而在类声明中,此类型将用作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());
    }
}

此“属性”在外部可以作为LiveDataMutableLiveData的超类型)看到,但是在类内部可以将其用作MutableLiveData

我想说听起来很自然,但是Kotlin似乎不允许这样做。我想念什么吗?还是创建private val _private = Implementation()val _public: SomeInterface = _private或实现具有getter语义和具有SomeInterface返回类型的修改名称的自定义方法是实现此目的的唯一方法?

1 个答案:

答案 0 :(得分:3)

我认为(如果我正确理解了您的问题)明确声明member的类型将满足您的要求,例如

interface SomeInterface

class Implementation : SomeInterface

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

更新:在提问后进行了更新,以澄清测试类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类型。