如果我不想在Kotlin中使用卑鄙的类调用基类的构造函数,该怎么办?

时间:2019-12-18 10:44:51

标签: kotlin constructor

有什么方法可以创建Derived的实例,但不能调用Base的构造函数?

open class Base(p: Int)

class Derived(p: Int) : Base(p)

3 个答案:

答案 0 :(得分:2)

您实际上可以做到

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,将会破坏逻辑。

答案 1 :(得分:1)

这是不可能的。派生类的构造函数必须调用基类的(任何)构造函数才能初始化基类的内容(字段)。

在Java中也是如此。只是默认构造函数是默认调用的(如果构造函数中未提供任何参数),但是如果您必须在带有参数的构造函数之间进行选择,则必须始终显式调用它们,因为必须选择要传递给构造函数。

答案 2 :(得分:0)

您必须始终调用超类的构造函数,以确保初始化了类的基础。但是您可以通过在基类中提供无参数的构造函数来解决问题。像这样:

open class Base(p: Int?){
    val p: Int? = p
    constructor(): this(null)
}

class Derived(p: Int) : Base()

处理基类的默认构造函数和参数可为空等的方式在很大程度上取决于特定情况。