본문 바로가기
Android

[Kotlin] Class 생성자

by bryan.oh 2023. 8. 1.
반응형

 

간단한 Class

class User(var name: String)
val user1 = User("Hello")
println(user1.name)
// Hello
user1.name = "Bryan"
println(user1.name)
// Bryan

위의 class 에서 var 대신 val 로 수정하면, 아래 라인에서 오류 발생

user1.name = "Bryan"  // 오류

 

일반적인 Class

class User {
    var name: String? = null
    var age: Int? = null
    lateinit var group: String
}
val user1 = User()
user1.name = "hello"

print(user1.name)
// hello

lateinit 를 할당하지 않은 상태에서 사용하면

print(user1.group)
// 오류발생 : Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property group has not been initialized

 

lateinit 의 변수에 값을 할당하려면,

사용전에 할당 하거나

val user1 = User()
user1.group = "Grade1"
print(user1.group)
// Grade1

아래와 같이 init 에서 할당해도 됩니다.

class User {
    var name: String? = null
    var age: Int? = null
    lateinit var group: String
    
    init {
        println("init")
        group = "Grade1"
    }
}
val user1 = User()
user1.name = "hello"

print(user1.group)
// Grade1

 

init 에서 하는 작업

흔한 예를 들면, 값 체크

class User(var name: String) {
    var age: Int? = null
    lateinit var group: String
    
    init {
    	if (name.isEmpty()){
            throw IllegalArgumentException("name cannot be empty string")
        }
    }
}
val user1 = User("") // 오류
// Exception in thread "main" java.lang.IllegalArgumentException: name cannot be empty string

 

생성자에서 파라메터를 받아서 초기화 하는 방법

class User(var name: String?) {
    var age: Int? = null
    lateinit var group: String
}
val user1 = User()  // 오류발생
// No value passed for parameter 'name'
val user1 = User("hello")
print(user1.name)
// hello

 

여러 생성자를 사용하고 싶다면

class User(var name: String? = "hello", var age: Int = 10) {
    lateinit var group: String
}
val user1 = User()
println(user1.name)
println(user1.age)
// hello
// 10

val user2 = User("bryan")
println(user2.name)
println(user2.age)
// bryan
// 10

val user3 = User("Kotlin", 20)
println(user3.name)
println(user3.age)
// Kotlin
// 20

constructor 사용

class User {
    var name: String? = null
    var age: Int? = null
    lateinit var group: String
    
    constructor() {
        println("constructor()")
    }
    
    constructor(name: String?){
        println("constructor($name)")
        this.name = name
    }
    
    constructor(name: String?, age: Int?, group: String){
        println("constructor($name, $age)")
        this.name = name
        this.age = age
        this.group = group
    }
}
val user1 = User()
println(user1.name)
println(user1.age)

val user2 = User("bryan")
println(user2.name)
println(user2.age)

val user3 = User("Kotlin", 20, "Grade01")
println(user3.name)
println(user3.age)
println(user3.group)

// constructor()
// null
// null
// constructor(bryan)
// bryan
// null
// constructor(Kotlin, 20)
// Kotlin
// 20
// Grade01

이 Class 의 마지막 두개 constructor 에서 name에 할당하는 코드가 각각 있는데, 합치려면

마지막 constructor 를 다음과 같이 수정하면 됩니다.

    constructor(name: String?, age: Int?, group: String):this(name){
        println("constructor($name, $age)")
        this.age = age
        this.group = group
    }

뒤에 붙은 :this(name) 은 name 하나만 parameter 로 받는 생성자를 호출합니다.

순서는 다음과 같습니다.

val user3 = User("Kotlin", 20, "Grade01")

// constructor(Kotlin)
// constructor(Kotlin, 20)

 

init 과 constructor 의 실행 순서

class User {
    var name: String? = null
    var age: Int? = null
    lateinit var group: String
    
    init {
        println("init")
    }
    
    constructor(name: String?){
        println("constructor(name)")
        this.name = name
    }
    
    constructor(name: String?, age: Int?): this(name){
        println("constructor(name, age)")
        this.age = age
    }
    
    constructor(name: String?, age: Int?, group: String): this(name, age){
        println("constructor(name, age, group)")
        this.group = group
    }
}

위와 같은 init 과 class constructor 가 있을 때, 마지막 constructor 를 사용하여 class 를 생성한다면,

실행 순서는 다음과 같습니다.

val user1 = User("Hello", 30, "Grade1")
// init
// constructor(name)
// constructor(name, age)
// constructor(name, age, group)



// 두번째 constructor 를 사용한다면,
val user2 = User("Hello", 30)
// init
// constructor(name)
// constructor(name, age)

 

728x90
반응형

댓글