属性 getter 键入超类型而不是 Kotlin 中的实现
Property getter typed on Supertype instead of Implementation in Kotlin
假设我有两个 类,一个 Base
和一个扩展 Base
.
的 Impl
package mypackage
open class Base
class Impl : Base()
我如何为具体的 Impl
-Type(供内部使用) 创建一个 private 属性 public getter类型为Base
-Type,实现多态?我最初的做法是这样的:
class Test {
private val myType = Impl()
get():Base
}
但是,Kotlin 编译器抱怨:
Error:(30, 11) Kotlin: Getter return 类型必须等于 属性 的类型,即 'mypackage.Impl'
基本上,这就是它在普通 Java:
中的样子
public class Test {
private Impl myImpl = new Impl();
public Base getBase() {
return myImpl;
}
}
如何才能做到这一点?我错过了什么吗?
P.S。我知道支持字段和创建自定义方法作为 getter 的解决方法,我只是好奇如何以优雅的 Kotlin 风格方式处理它。
如果 属性 是私有的,那么 getter 也是私有的。在这种情况下,它的类型无关紧要。如果你想要一个 public 属性 的基类型,你需要单独声明它:
private val _myType = Impl()
public val myType : Base
get() = _myType
您可以像在 Java 中一样编写代码,使用两个不同的属性。除非你同意 Impl
永远不要专攻 class。所以这里有很多选择:
// 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
}
假设我有两个 类,一个 Base
和一个扩展 Base
.
Impl
package mypackage
open class Base
class Impl : Base()
我如何为具体的 Impl
-Type(供内部使用) 创建一个 private 属性 public getter类型为Base
-Type,实现多态?我最初的做法是这样的:
class Test {
private val myType = Impl()
get():Base
}
但是,Kotlin 编译器抱怨:
Error:(30, 11) Kotlin: Getter return 类型必须等于 属性 的类型,即 'mypackage.Impl'
基本上,这就是它在普通 Java:
中的样子public class Test {
private Impl myImpl = new Impl();
public Base getBase() {
return myImpl;
}
}
如何才能做到这一点?我错过了什么吗?
P.S。我知道支持字段和创建自定义方法作为 getter 的解决方法,我只是好奇如何以优雅的 Kotlin 风格方式处理它。
如果 属性 是私有的,那么 getter 也是私有的。在这种情况下,它的类型无关紧要。如果你想要一个 public 属性 的基类型,你需要单独声明它:
private val _myType = Impl()
public val myType : Base
get() = _myType
您可以像在 Java 中一样编写代码,使用两个不同的属性。除非你同意 Impl
永远不要专攻 class。所以这里有很多选择:
// 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
}