属性获取器在Supertype上输入而不是在Kotlin中实现

时间:2015-08-06 11:25:45

标签: kotlin

假设我有两个类,BaseImpl,它们扩展了Base

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;
    }
}

怎么能实现这个目标?我错过了什么吗?

P.S。我知道Backing Fields和创建自定义方法作为getter的解决方法,我只是对如何以优雅的Kotlin风格方式处理它感到好奇。

2 个答案:

答案 0 :(得分:6)

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

private val _myType = Impl()

public val myType : Base
    get() = _myType

答案 1 :(得分:1)

使用两个不同的属性,您将使用与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
}