【发布时间】:2020-04-10 21:41:47
【问题描述】:
有什么方法可以创建Derived 的实例但不调用Base 的构造函数?
open class Base(p: Int)
class Derived(p: Int) : Base(p)
【问题讨论】:
标签: kotlin constructor
有什么方法可以创建Derived 的实例但不调用Base 的构造函数?
open class Base(p: Int)
class Derived(p: Int) : Base(p)
【问题讨论】:
标签: kotlin constructor
其实你可以的
import sun.misc.Unsafe
open class Base(p: Int){
init {
println("Base")
}
}
class Derived(p: Int) : Base(p){
init {
println("Derived")
}
}
fun main() {
val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe").apply {
isAccessible = true
}.get(null) as Unsafe
val x = unsafe.allocateInstance(Derived::class.java)
println("X = $x")
}
但不要这样,此解决方案是一种低级机制,旨在仅供核心 Java 库使用,而不能由标准用户使用。如果你使用它,你会破坏 OOP 的逻辑。
【讨论】:
这是不可能的。派生类的构造函数必须调用基类的(任何)构造函数来初始化基类的内容(字段)。
Java 中也是如此。只是默认调用了默认构造函数(如果构造函数中没有提供参数),但是如果必须在带参数的构造函数之间进行选择,则始终必须显式调用它们,因为您必须选择将哪些值传递给构造函数。
【讨论】:
您必须始终调用超类的构造函数以确保初始化该类的基础。但是您可以通过在基类中提供无参数构造函数来解决您的问题。像这样的:
open class Base(p: Int?){
val p: Int? = p
constructor(): this(null)
}
class Derived(p: Int) : Base()
你处理基类的哪个构造函数是默认的,哪些参数可以为空等的方式将在很大程度上取决于具体情况。
【讨论】: