Реализовать шаблон нулевого объекта - PullRequest
0 голосов
/ 03 марта 2019

Я нашел этот вопрос , который определенным образом реализует шаблон нулевого объекта в 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 {
    }
}

, но это даже не компилируется.

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Один из способов добиться этого - использовать 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

0 голосов
/ 03 марта 2019

Вы на правильном пути, проблема, с которой вы столкнетесь, заключается в том, что вы не можете наследовать от класса данных.

Вы можете либо реструктурировать свой код, чтобы использовать интерфейс, что-то вродеthis:

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)
...