1

我发现这个问题以某种方式在 Kotlin 中实现了空对象模式。我通常在 Java 中做一些不同的事情:

class MyClass {
    static final MyClass INVALID = new MyClass();

    public MyClass() {
       // empty
    }
}

这样,我总是可以MyClass.INVALID用作空对象。

如何在 Kotlin 中实现这种风格?

我摆弄了这样的事情:

data class MyClass(val id: Int) {
    object INVALID: MyClass {
    }
}

但这甚至无法编译。

4

2 回答 2

4

实现此目的的一种方法是使用companion object. 因为可以通过简单地使用类名作为限定符来调用伴生对象的成员。你可以这样做;

data class MyClass(val id: Int) {
    companion object {
        @JvmStatic
        val nullInstance = MyClass(0)  //0 or any intended value
    }
}

//invocation
 val a = MyClass.nullInstance
 val b = MyClass.nullInstance
 print(a == b) //prints true because these are equavalent to Java's static instances.

在这里,我已将其注释nullInstance@JvmStatic将其生成为真正的静态成员。

https://kotlinlang.org/docs/reference/object-declarations.html

于 2019-03-03T20:31:08.640 回答
0

你在正确的轨道上,你会遇到的问题是你不能从数据类继承。

您可以重组代码以使用接口,如下所示:

interface MyClass {
    val id: Int

    object INVALID : MyClass {
        override val id: Int = -1
    }
}

data class RealMyClass(override val id: Int) : MyClass

或者有一个open class可以继承的作为基础,这为您提供了更简洁的代码,因为您可以在 null 对象的情况下重用基类中声明的属性 - 您仍然必须在数据中覆盖它类,因为所有数据类构造函数参数都需要是属性。

open class MyClass(open val id: Int) {
    object INVALID : MyClass(-1)
}

data class RealMyClass(override val id: Int) : MyClass(id)
于 2019-03-03T20:29:36.450 回答