web-dev-qa-db-ja.com

Kotlinデータクラスに複数のコンストラクターを含めることはできますか?

データクラスは、デフォルトでゲッターとセッターを備えたkotlinの単純なモデルに似ており、次のように単純であることを知っています。

data class User(val name: String, val age: Int)

そのデータクラスの2番目のコンストラクタを宣言することはできますか?

29
Eder Padilla

このようにデータクラスを設定できます

data class User(val name: String? = null, val id: String? = null, val email: String? = null)

このような複数のコンストラクターでオブジェクトをインスタンス化できます

val userId = User(id = "123456")
        val userMail = User(email= "[email protected]")
        val userName = User("Name")
0
Eder Padilla

はい。ただし、各変数は初期化する必要があります。そのため、次のようにデータクラスコンストラクターでデフォルトの引数を設定できます。

_data class Person(val age: Int, val name: String = "Person without name")
_

これで、このデータクラスのインスタンスを2つの方法で作成できます

  • Person(30)
  • Person(20, "Bob")
18

Kotlinデータクラスには、少なくとも1つのメンバーを定義するプライマリコンストラクターが必要です。それ以外に、 クラスと継承-二次コンストラクター で説明されているように、二次コンストラクターを追加できます。

クラスおよび例のセカンダリコンストラクターの場合:

data class User(val name: String, val age: Int) {
    constructor(name: String): this(name, -1) { ... }
}

セカンダリコンストラクターは、その定義でプライマリコンストラクターに委任する必要があることに注意してください。

セカンダリコンストラクターに共通する多くのことは、パラメーターにデフォルト値を設定することで解決できます。上記の場合、次のように単純化できます。

data class User(val name: String, val age: Int = -1) 

これらをJavaから呼び出す場合は、 Java interop-Java Kotlinの呼び出し オーバーロードの生成方法に関するドキュメント、および場合によっては NoArg Compiler Plugin 他の特別な場合。

18
Jayson Minard

データクラスの更新された回答:

はい、できますが、すべてをプライマリコンストラクターに委任する必要があります。

data class User(val name: String, val age: Int)
{
    constructor(name: String): this(name, -1) {
    }

    constructor(age: Int): this("Anon", age) {
    }
}

// Anon name: Anon
println("Anon name: " + User(30).name)

// No age: -1
println("No age: " + User("Name").age)

// Name: Name age: 20
val u = User("Name", 20)
println("Name: " + u.name + " age: " + u.age)

Alexeyが行ったように、プライマリコンストラクターにデフォルト値を設定することもできます。

4
Robert

はい、以下のコードのように使用できます。データクラスのプライマリコンストラクターには、1つ以上のパラメーターが必要です。

data class SampleData(val name: String, val age: Int) {
    constructor(name: String, age: Int, email: String) : this(name, age) {

    }
}

プライマリコンストラクターの既定値により、セカンダリコンストラクターの多くの必要性がなくなりますが、必要なインスタンスが、分析する必要があるデータに基づくロジックに依存している場合、コンパニオンオブジェクトを使用する方が良いかもしれません。

data class KeyTag(val a: String, val b: Int, val c: Double) {
    companion object Factory {
        val empty = KeyTag("", 0, 0.0)

        fun create(bigString: String): KeyTag {
            // Logic to extract appropriate values for arguments a, b, c
            return KeyTag(a, b, c)
        }

        fun bake(i: Int): KeyTag = KeyTag("$i", i, i.toDouble())
    }
}

使用法は次のとおりです。

val ks = KeyTag.create("abc:1:10.0")
val ke = KeyTag.empty
val kb = KeyTag.bake(2)
1
Mike Hanafey

データクラスは一貫性と意味のある動作を保証しますが、不変性のためにvalが必要です。

data class SampleData(val name: String, val age: Int, val email: String ?= null) {
constructor(name: String, age: Int) : this(name, age, null) {

}

}

セカンダリコンストラクターは、その定義でプライマリコンストラクターに委任する必要があるため、不変性を維持するために、「null」が機能します。

0
boopathiraja

デフォルトのパラメーター値を置き換えるこの関数のオーバーロードを生成するようKotlinコンパイラーに指示します。メソッドにN個のパラメーターがあり、Mにデフォルト値がある場合、M個のオーバーロードが生成されます。最初のパラメーターはN-1個のパラメーター(最後のパラメーターを除くすべてがデフォルト値を取る)、2番目のパラメーターはN-2個のパラメーター、オン。

data class User @JvmOverloads  constructor(
var email: String="",
var password: String=""

0
RanaUmer