https://kotlinlang.org/docs/reference/classes.html
kotlin公式のセカンダリコンストラクタのサンプルコードです。
class Person(val name: String) { constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
上記コードの説明で委譲という言葉を使っていますが、噛み砕くとどいう意味なのでしょうか?
今回の例だと、セカンダリコンストラクタを呼んだときに
: this(name)
と、ありますが、これはプライマリコンストラクタを呼ぶための記述ということで合っていますでしょうか?
(単にセカンダリ→プライマリと順に呼んでいきインスタンスを作成する、という意味で委譲ということ・・・?)
また、parent.children.add(this)
でadd(this)
とありますが、このthisは1つ目のthis
と違いclass自体を呼んでいます。
これはどういうことでしょうか?
コンストラクタを呼んで初期化の最後の段階に自分自身のインスタンスを(this)として呼んだ ということでしょうか?
どなたか分かる方居ましたら教えていただきいたいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
プライマリコンストラクタが定義されているクラスでは、セカンダリコンストラクタでインスタンスを生成する場合、直接的または間接的にプライマリコンストラクタを呼び出す必要があります。
kotlin
1// Primary constructor 2class Person constructor(val name: String) { 3 // Secondary constructor (A) 4 // このコンストラクタのthis(...)はプライマリコンストラクタを呼んでいます 5 constructor(name: String, age: Int, person: Person) : this(name) { 6 person.children.add(this) 7 this.age = age 8 } 9 // Secondary constructor (B) 10 // このコンストラクタのthis(...)は上記のSecondary consutructor (A)を呼んでいます 11 constructor(name: String, person: Person) : this(name, 0, person) { 12 } 13 14 var age: Int = 0 15 val children = mutableListOf<Person>() 16 17 override fun toString(): String { 18 return "Person(name='$name', age=$age, children=$children)" 19 } 20 21}
上記のコードでいえば、Secondary constructor (A)が直接プライマリコンストラクタを呼び出しています。
また、Secondary constructor (B)ではSecondary constructor (A)を経由して間接的にプライマリコンストラクタを呼び出しています。
今回の例だと、セカンダリコンストラクタを呼んだときに
: this(name)
と、ありますが、これはプライマリコンストラクタを呼ぶための記述ということで合っていますでしょうか?
この例で言えばその認識であっていると思いますが、正確には他のコンストラクタを呼び出す記述です。(プライマリコンストラクタでなくてもいいということです)
"Kotlin","コンストラクタ"等のキーワードで検索すれば詳しく解説しているサイトが見つかると思いますのでご確認ください。
また、parent.children.add(this)
でadd(this)とありますが、このthisは1つ目のthisと違いclass自体を呼んでいます。これはどういうことでしょうか?
このthis
キーワードは自分自身のインスタンスを指すキーワードです。
コンストラクタで使われていたthis
は他のコンストラクタを呼び出すthis
キーワードです。
つまりthis
キーワードには2通りの使い方があるということになります。
Keywords and Operatorsからthis
キーワードの説明を下記に引用します。
refers to the current receiver
(現在のレシーバを参照します)
calls another constructor of the same class from a secondary constructor
(セカンダリコンストラクタから同じクラスの別のコンストラクタを呼び出す)
この処理は自分自身のインスタンス(this)を、コンストラクタ引数に渡されたPersonインスタンスのchildrenプロパティに追加している処理になります。
kotlin
1person.children.add(this)
下記のサンプルコードで確認すると分かりやすいと思います。
kotlin
1fun main(args: Array<String>) { 2 val father = Person("父") 3 val son = Person("息子", 5, father) 4 val daughter = Person("娘", father) 5 6 println(father) 7 println(son) 8 println(daughter) 9 // Person(name='父', age=0, children=[Person(name='息子', age=5, children=[]), Person(name='娘', age=0, children=[])]) 10 // Person(name='息子', age=5, children=[]) 11 // Person(name='娘', age=0, children=[]) 12 13}
2019/02/14追記
下記のコードは、回答欄に記述したクラスのプライマリコンストラクタを少し修正したものです。
class Person constructor(name: String) { // このブロック内のコードがプライマリコンストラクタ呼び出し時に実行される val name: String = name //コンストラクタの引数でプロパティを初期化 var age: Int = 0 // デフォルト値で初期化 val children= mutableListOf<Person>() // 同上 // init blockはそのあとに実行される init { println("Init Block. name=${this.name} age=${this.age} children=${this.children.size}") } }
さらに、initブロックが記述されていればプリライマリコンストラクタの実行後に実行されます。
この時点で処理の順番はインスタンス生成 → プライマリコンストラクタ → initブロック → セカンダリコンストラクタになります。
試しにinitブロックやコンストラクタ内にprint文を入れて実行してみると次のようになります。
kotlin
1class Person constructor(name: String) { 2 val name: String = name 3 var age: Int = 0 4 val children= mutableListOf<Person>() 5 6 // Init Block 7 init { 8 println("Init Block. name=${this.name} age=${this.age} children=${this.children.size}") 9 } 10 11 // Secondary constructor (A) 12 constructor(name: String, age: Int, person: Person) : this(name) { 13 println("constructor A. age=${this.age} children=${this.children.size}") 14 person.children.add(this) 15 this.age = age 16 } 17 // Secondary constructor (B) 18 constructor(name: String, person: Person) : this(name, 0, person) { 19 println("constructor B. age=${this.age} children=${this.children.size}") 20 } 21 22 override fun toString(): String { 23 return "Person(name='$name', age=$age, children=$children)" 24 } 25 26}
実行してみます。
kotlin
1val father = Person("父") 2// Init Block. name=父 age=0 children=0 3println(father) 4// Person(name='父', age=0, children=[]) 5 6val son = Person("息子", 5, father) 7// Init Block. name=息子 age=0 children=0 8// constructor A. age=0 children=0 9println(son) 10// Person(name='息子', age=5, children=[]) 11 12val daughter = Person("娘", father) 13// Init Block. name=娘 age=0 children=0 14// constructor A. age=0 children=0 15// constructor B. age=0 children=0 16println(daughter) 17// Person(name='娘', age=0, children=[])
投稿2019/02/12 14:37
編集2019/02/13 15:29総合スコア1752
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/13 11:10
2019/02/13 15:29 編集
2019/02/14 15:08