实现空对象模式

时间:2019-03-03 20:17:01

标签: kotlin null-object-pattern

我发现this question以某种方式在Kotlin中实现了空对象模式。我通常在Java中会做些不同:

[["Milk", 95520, 3.27, 20],
 ["Eggs", 55504, 2.97, 15],
 ["Bread", 57971, 2.78, 20],
 ["Apples", 19791, 0.78, 70],
 ["Cheese Bits", 32510, 2.99, 25],
 ["Cheese Bytes", 84159, 23.92, 10]]

通过这种方式,我始终可以将class MyClass { static final MyClass INVALID = new MyClass(); public MyClass() { // empty } } 用作空对象。

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

我摆弄着这样的东西:

MyClass.INVALID

但是它甚至不能编译。

2 个答案:

答案 0 :(得分:3)

您可以使用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

答案 1 :(得分:0)

您处在正确的轨道上,那样会遇到的问题是您无法从数据类继承。

您可以重组代码以使用接口,例如:

interface MyClass {
    val id: Int

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

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

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

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

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