属性getter在Supertype上输入,而不是在Kotlin中执行

假设我有两个类,一个Base和一个扩展BaseImpl

 package mypackage open class Base class Impl : Base() 

我将如何创建一个私有属性的具体Impl类型(内部使用) ,与一个公共的getter键入为Base类型 ,实现多态? 我最初的方法是这样的:

 class Test { private val myType = Impl() get():Base } 

但是,Kotlin编译器抱怨:

错误:(30,11)Kotlin:Getter返回类型必须等于属性的类型,即'mypackage.Impl'

基本上,这就是它在普通Java中的样子:

 public class Test { private Impl myImpl = new Impl(); public Base getBase() { return myImpl; } } 

怎么能做到这一点? 我错过了什么吗?

PS我知道Backing Fields和创建自定义方法作为getter的解决方法,我只是好奇如何以优雅,Kotlin风格的方式来处理这个问题。

如果财产是私人的,那么吸收者也是如此。 在这种情况下,它将具有什么类型并不重要。 如果您想拥有基本类型的公共属性,则需要单独声明它:

 private val _myType = Impl() public val myType : Base get() = _myType 

你可以使用两个不同的属性来编码,就像你在Java中一样。 除非Impl从来没有被专业化。 所以这里有很多选择:

 // if you don't need Impl typed as Impl then just hold it as base class Test1 { public val base: Base = Impl() } // have both with pointing one reference at the other class Test2 { private val _impl = Impl() public val base: Base = _impl } // have both, second one is a getter (no real benefit over Test2) class Test3 { private val _impl = Impl() public val base: Base get() = _impl } // use a function to do basically a cast class Test4 { private val _impl = Impl() public fun asBase(): Base = _impl } 

或者别担心这个其他的属性,任何使用Impl都可以把它保存为Base类型:

 class Test5 { public val impl: Impl = Impl() } // later val thing: Base = Test5().impl 

也许你正在用一个通用的接口来构建这个基础实现?

 open class Base {} // a common way to get the implementation from within a class interface Based { val base: Base } class ImplAbc : Base() class ImplXyz : Base() class TestAbc : Based { override val base: Base = ImplAbc() } class TestXyz : Based { private val _impl = ImplXyz() override val base: Base = _impl }