빈 ꡬ멍 μ±„μš°κΈ°

[Kotlin] init 블둝

⭐⭐기둝 2024. 11. 4. 18:45

좜처

https://kotlinlang.org/docs/classes.html#constructors

 

Classes | Kotlin

 

kotlinlang.org

https://kotlinlang.org/docs/inheritance.html#derived-class-initialization-order

 

Inheritance | Kotlin

 

kotlinlang.org

 

 


클래슀의 μ΄ˆκΈ°ν™”

κΈ°λ³Έ μƒμ„±μžλŠ” 클래슀 헀더(클래슀의 이름과 μ£Όμƒμ„±μž)μ—μ„œ 클래슀 μΈμŠ€ν„΄μŠ€μ™€ ν•΄λ‹Ή 속성을 μ΄ˆκΈ°ν™”ν•œλ‹€. 객체 생성 쀑에 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ €λ©΄ 클래슀 λ³Έλ¬Έ 내뢀에 μ΄ˆκΈ°ν™” 블둝을 μ‚¬μš©ν•œλ‹€. μ΄ˆκΈ°ν™” 블둝은 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

 

  1. 클래슀 내뢀에 μœ„μ—μ„œλΆ€ν„° μ•„λž˜ μˆœμ„œλ‘œ μ„ μ–Έλœ 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

 

  1. λ¨Όμ € μ£Ό μƒμ„±μžλ‘œ ν˜ΈμΆœν•˜λŠ” 객체 μ΄ˆκΈ°ν™” 루트λ₯Ό 탄닀. 클래슀의 μœ„μ—μ„œ μ•„λž˜λ‘œλΆ€ν„° μ„ μ–Έλœ init 블둝을 μ‹€ν–‰ν•œλ‹€.
  2. κ·Έ λ‹€μŒ ν˜ΈμΆœν•œ λΆ€ μƒμ„±μžμ˜ μ½”λ“œ 블둝을 μ‹€ν–‰ν•œλ‹€.

 

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
  1. λ¨Όμ € μ£Ό μƒμ„±μžλ‘œ ν˜ΈμΆœν•˜λŠ” 객체 μ΄ˆκΈ°ν™” 루트λ₯Ό 탄닀. 클래슀의 μœ„μ—μ„œ μ•„λž˜λ‘œλΆ€ν„° μ„ μ–Έλœ init 블둝을 μ‹€ν–‰ν•œλ‹€.
  2. κ·Έ λ‹€μŒ 객체 생성을 μœ„μž„ν•œ λΆ€ μƒμ„±μžμ˜ μ½”λ“œ 블둝을 μ‹€ν–‰ν•œλ‹€.
  3. λ§ˆμ§€λ§‰μœΌλ‘œ ν˜ΈμΆœν•œ λΆ€ μƒμ„±μžμ˜ μ½”λ“œ 블둝을 μ‹€ν–‰ν•œλ‹€.