์ถ์ฒ
https://kotlinlang.org/docs/classes.html#constructors
https://kotlinlang.org/docs/inheritance.html#derived-class-initialization-order
ํด๋์ค์ ์ด๊ธฐํ
๊ธฐ๋ณธ ์์ฑ์๋ ํด๋์ค ํค๋(ํด๋์ค์ ์ด๋ฆ๊ณผ ์ฃผ์์ฑ์)์์ ํด๋์ค ์ธ์คํด์ค์ ํด๋น ์์ฑ์ ์ด๊ธฐํํ๋ค. ๊ฐ์ฒด ์์ฑ ์ค์ ์ฝ๋๋ฅผ ์คํํ๋ ค๋ฉด ํด๋์ค ๋ณธ๋ฌธ ๋ด๋ถ์ ์ด๊ธฐํ ๋ธ๋ก์ ์ฌ์ฉํ๋ค. ์ด๊ธฐํ ๋ธ๋ก์ init ํค์๋ ๋ค์ ์ค๊ดํธ๋ฅผ ๋ถ์ฌ ์ ์ธํ๋ค. ์คํํ๋ ค๋ ์ฝ๋๋ ์ค๊ดํธ ์์ ์์ฑํ๋ค.
์ธ์คํด์ค๋ฅผ ์ด๊ธฐํ ์ค์ ์ด๊ธฐํ ๋ธ๋ก๊ณผ ์์ฑ ์ด๊ธฐํ๋ ํด๋์ค ์์ ๊ธฐ์ ๋ ์์(์์์ ์๋)๋ก ์คํ๋๋ค.
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints $name")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main() {
InitOrderDemo("hello")
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// First property: hello
// First initializer block that prints hello
// Second property: 5
// Second initializer block that prints 5
๋ถ ์์ฑ์
ํด๋์ค๋ constructor ํค์๋๋ฅผ ์ฌ์ฉํด ๋ถ ์์ฑ์๋ฅผ ๋ง๋ค ์ ์๋ค.
class Person(val pets: MutableList<Pet> = mutableListOf())
class Pet {
constructor(owner: Person) {
owner.pets.add(this) // adds this pet to the list of its owner's pets
}
}
ํด๋์ค์ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์๋ ๊ฒฝ์ฐ, ๊ฐ ๋ณด์กฐ ์์ฑ์๋ ๊ธฐ๋ณธ ์์ฑ์์๊ฒ ์ง์ ์์ํ๊ฑฐ๋, ๋ค๋ฅธ ๋ณด์กฐ ์์ฑ์๋ค๋ก ๊ฐ์ ์ ์ผ๋ก ์์ฑ์ ์์ํ ์ ์๋ค. ๋ค๋ฅธ ์์ฑ์์๊ฒ ์์ํ ๋ this ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
class Person(val name: String) {
val children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
์ด๊ธฐํ ์ฝ๋๋ ๊ธฐ๋ณธ ์์ฑ์์ ์ผ๋ถ๊ฐ ๋๋ค. ๊ธฐ๋ณธ ์์ฑ์์ ์์ํ๋ ๊ฒ์ด ๋ถ ์์ฑ์์ ์ฒซ์งธ ๋ฌธ์์ ์ ๊ทผํ๋ ๋์ ์ผ์ด๋์ , ๋ถ ์์ฑ์์ ์ฝ๋ ๋ธ๋ก์ ๋ชจ๋ init ๋ธ๋ก๊ณผ ์์ฑ์ ์ด๊ธฐํ๊ฐ ๋ค ์คํ๋ ํ์ ์คํ๋๋ค.
ํด๋์ค์ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์๋๋ผ๋, ์์์ ์๋ฌต์ ์ผ๋ก ๋ฐ์ํด์ ์ด๊ธฐํ ๋ธ๋ก์ด ๊ณ์ ์คํ๋๋ค.
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor $i")
}
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// Init block
// Constructor 1
ํด๋์ค ์์์ ๊ฒฝ์ฐ init ๋ธ๋ก์ ์คํ
์์ ํด๋์ค๊ฐ ์ ์ธ์คํด์ค๋ฅผ ์์ํ๋ ๋์ ๋ถ๋ชจ ํด๋์ค์ ์ด๊ธฐํ๊ฐ ๋งจ ๋จผ์ ์ํ๋๋ค. ๊ทธ ํ์ ์์ ํด๋์ค์ ์ด๊ธฐํ๊ฐ ์งํ๋๋ค.
open class Base(val name: String) {
init { println("Initializing a base class") }
open val size: Int =
name.length.also { println("Initializing size in the base class: $it") }
}
class Derived(
name: String,
val lastName: String,
) : Base(name.replaceFirstChar { it.uppercase() }.also { println("Argument for the base class: $it") }) {
init { println("Initializing a derived class") }
override val size: Int =
(super.size + lastName.length).also { println("Initializing size in the derived class: $it") }
}
fun main() {
println("Constructing the derived class(\"hello\", \"world\")")
Derived("hello", "world")
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// Constructing the derived class("hello", "world")
// Argument for the base class: Hello
// Initializing a base class
// Initializing size in the base class: 5
// Initializing a derived class
// Initializing size in the derived class: 10
๋ถ๋ชจ ํด๋์ค๊ฐ ์์ฑ์๊ฐ ์คํ๋ ๋, ์์ ํด๋์ค์์ ์ ์ธ๋๊ฑฐ๋ ์ค๋ฒ๋ผ์ด๋๋ ํ๋กํผํฐ๋ ์์ง ์ด๊ธฐํ๋์ง ์์ ์ํ์ด๋ค. ๋ถ๋ชจ ํด๋์ค ์ด๊ธฐํ์์ ์์ง ์ด๊ธฐํ๋์ง ์์ ์์ ํด๋์ค์ ํ๋กํผํฐ๋ค์ ์ฌ์ฉํ๋ฉด ์๋ชป๋ ๋์์ด๋ ๋ฐํฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค. ๊ทธ๋์ ๋ถ๋ชจ ํด๋์ค๋ฅผ ์ค๊ณํ ๋์๋ ์์ฑ์์ open ํ๋กํผํฐ, ํ๋กํผํฐ ์ด๊ธฐํ ์์ , init ๋ธ๋ก์ ์ฌ์ฉํ์ง ์๋๋ก ํผํด์ผ ํ๋ค.
ํด๋์ค ๋ถ ์์ฑ์์ init ๋ธ๋ก ์คํ ์์ ํ์ธํ๊ธฐ
1. ์ฃผ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ. ํด๋์ค ์์ ์ฌ๋ฌ init ๋ธ๋ก์ด ์๋ ๊ฒฝ์ฐ
class Person(val name: String, val age: Int){ // -> ํธ์ถ. ์ฃผ ์์ฑ์๋ก ๊ฐ์ฒด ์์ฑ
init { // -> ์คํ 1
println("primary constructor : $name, $age")
}
constructor() : this(name= "none", age= 0) {
println("secondary constructor $name, $age")
}
constructor(message: String) : this() {
println("secondary constructor 2 : $name, $age")
}
init { // -> ์คํ 2
println("primary constructor 2 : $name, $age")
}
}
fun main() {
Person("Alice", 29)
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// primary constructor : Alice, 29
// primary constructor 2 : Alice, 29
- ํด๋์ค ๋ด๋ถ์ ์์์๋ถํฐ ์๋ ์์๋ก ์ ์ธ๋ init ๋ธ๋ก์ ์คํํ๋ค.
2. ๋ถ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ, ๊ฐ์ฒด ์์ฑ์ ์ฃผ ์์ฑ์์ ์์ํ๋ค. ํธ์ถํ๋ ๋ถ์์ฑ์๋ ์ฝ๋ ๋ธ๋ก์ผ๋ก ๋ถ ์์ฑ์์ init ๋ธ๋ก์ ์ ์ธํ๋ค.
class Person(val name: String, val age: Int){
init { // -> ์คํ 1
println("primary constructor : $name, $age")
}
constructor() : this(name= "none", age= 0) { // -> ํธ์ถ. ์ฃผ ์์ฑ์์๊ฒ ๊ฐ์ฒด ์์ฑ ์์
println("secondary constructor $name, $age") // -> ์คํ 3
}
constructor(message: String) : this() {
println("secondary constructor 2 : $name, $age")
}
init { // -> ์คํ 2
println("primary constructor 2 : $name, $age")
}
}
fun main() {
Person()
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// primary constructor : none, 0
// primary constructor 2 : none, 0
// secondary constructor none, 0
- ๋จผ์ ์ฃผ ์์ฑ์๋ก ํธ์ถํ๋ ๊ฐ์ฒด ์ด๊ธฐํ ๋ฃจํธ๋ฅผ ํ๋ค. ํด๋์ค์ ์์์ ์๋๋ก๋ถํฐ ์ ์ธ๋ init ๋ธ๋ก์ ์คํํ๋ค.
- ๊ทธ ๋ค์ ํธ์ถํ ๋ถ ์์ฑ์์ ์ฝ๋ ๋ธ๋ก์ ์คํํ๋ค.
2. ๋ถ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ, ๊ฐ์ฒด ์์ฑ์ ๋ค๋ฅธ ๋ถ ์์ฑ์์ ์์ํ๋ค. ํธ์ถํ๋ ๋ถ์์ฑ์๋ ์ฝ๋ ๋ธ๋ก์ผ๋ก ๋ถ ์์ฑ์์ init ๋ธ๋ก์ ์ ์ธํ๋ค.
class Person(val name: String, val age: Int){
init { // -> ์คํ 1
println("primary constructor : $name, $age")
}
constructor() : this(name= "none", age= 0) {
println("secondary constructor $name, $age") // -> ์คํ 3
}
constructor(message: String) : this() { // -> ํธ์ถ. ๋ค๋ฅธ ๋ถ ์์ฑ์์๊ฒ ๊ฐ์ฒด ์์ฑ ์์
println("secondary constructor 2 : $name, $age") // -> ์คํ 4
}
init { // -> ์คํ 2
println("primary constructor 2 : $name, $age")
}
}
fun main() {
Person("Hello World")
}
// (์ถ๋ ฅ ๊ฒฐ๊ณผ)
// primary constructor : none, 0
// primary constructor 2 : none, 0
// secondary constructor none, 0
// secondary constructor 2 : none, 0
- ๋จผ์ ์ฃผ ์์ฑ์๋ก ํธ์ถํ๋ ๊ฐ์ฒด ์ด๊ธฐํ ๋ฃจํธ๋ฅผ ํ๋ค. ํด๋์ค์ ์์์ ์๋๋ก๋ถํฐ ์ ์ธ๋ init ๋ธ๋ก์ ์คํํ๋ค.
- ๊ทธ ๋ค์ ๊ฐ์ฒด ์์ฑ์ ์์ํ ๋ถ ์์ฑ์์ ์ฝ๋ ๋ธ๋ก์ ์คํํ๋ค.
- ๋ง์ง๋ง์ผ๋ก ํธ์ถํ ๋ถ ์์ฑ์์ ์ฝ๋ ๋ธ๋ก์ ์คํํ๋ค.
'๋น ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android][View] getWidth(), getHeight() ์ measureWidth(), measuredHeight() (1) | 2024.11.13 |
---|---|
[Kotlin] ๋๋ค๋ ์๋ฐ๋ก ์ด๋ป๊ฒ ์ปดํ์ผ๋ ๊น (1) | 2024.11.12 |
[JVM] invokedynamic ์ดํดํ๊ธฐ (0) | 2024.11.01 |
[Kotlin] interface ์ default method๋ฅผ ์๋ฐ๋ก ๋ณํํ๊ธฐ (2) | 2024.10.29 |
[Kotlin] const val (0) | 2024.10.29 |