【问题标题】:What should I do if I don't want a devired class call base class's constructor in Kotlin?如果我不想在 Kotlin 中使用 devired 类调用基类的构造函数,我该怎么办?
【发布时间】:2020-04-10 21:41:47
【问题描述】:

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

open class Base(p: Int)

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

【问题讨论】:

    标签: kotlin constructor


    【解决方案1】:

    其实你可以的

    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 的逻辑。

    【讨论】:

    • 顺便说一句。
    【解决方案2】:

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

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

    【讨论】:

    • 确实如此。构造函数的重点是设置每个实例,使其进入一致状态。 Java 和 Kotlin 都确保始终调用构造函数(在每个级别),以便整个对象以一致的状态开始。
    【解决方案3】:

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

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

    你处理基类的哪个构造函数是默认的,哪些参数可以为空等的方式将在很大程度上取决于具体情况。

    【讨论】:

      猜你喜欢
      • 2017-05-10
      • 1970-01-01
      • 2017-01-04
      • 2011-06-21
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 2016-07-19
      相关资源
      最近更新 更多