属性getter在Supertype上输入,而不是在Kotlin中执行
假设我有两个类,一个Base
和一个扩展Base
的Impl
。
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 }