
코틀린의 생성자는 크게 주 생성자와 부 생성자로 나뉜다.
주 생성자는 클래스 이름 옆 괄호 안에 정의된다! 이 괄호 안에 매개변수를 적을 수 있다.
아래의 예시에서 Person 은 name 과 age 의 속성이 있으며 주 생성자를 통해 초기화 된다. init 블록은 객체 생성시 실행된다!
class Person(val name: String, var age: Int) {
init {
println("Person is created with name: $name and age: $age")
}
}
부 생성자는 constructor 키워드를 사용하여 정의한다.
아래의 예시에서도 name, age 의 속성을 가지고 이를 부생성자를 통해 초기화할 수 있다.
class Person {
var name: String
var age: Int
constructor(name: String, age: Int) {
this.name = name
this.age = age
println("Secondary constructor called with name: $name and age: $age")
}
}
주 생성자와 부 생성자를 함께 쓸 수도 있다. 이렇게 하면 Person 클래스는 name 과 age 를 초기화 하는 주 생성자와, name만을 초기화하고 age를 기본값인 0으로 설정하는 부 생성자를 가질 수 있다. 부 생성자는 this 키워드를 사용하여 주 생성자를 호출한다.
class Person(val name: String, var age: Int) {
init {
println("Person is created with name: $name and age: $age")
}
constructor(name: String) : this(name, 0) {
println("Secondary constructor called with name: $name")
}
}
만약 주 생성자에 private 키워드를 사용하면, 외부에서 객체 생성을 못하게 막을 수 있다. 이 방식은 싱글톤 패턴을 구현하거나 팩토리 메서드를 사용할 때 유용하게 사용된다.
class PrivateConstructor private constructor(val name: String) {
companion object {
fun create(name: String): PrivateConstructor {
return PrivateConstructor(name)
}
}
}
fun main() {
// val obj = PrivateConstructor("test") // 오류: 생성자가 private으로 설정되어 있음
val obj = PrivateConstructor.create("test")
println(obj.name) // "test" 출력
}
부 생성자에도 private 키워드를 생성할 수 있다.
아래의 예시에서 주 생성자: private constructor(val name: String, val age: Int)는 비공개로 설정되어 외부에서 직접 호출할 수 없으며, 비공개 부 생성자인 private constructor(name: String, age: Int, secret: String)는 외부에서 직접 호출할 수 없다. 이건, 클래스 내부에서 사용 가능하다.
constructor(name: String)는 공개된 부 생성자로, name만을 초기화하고 age는 0으로 설정하는 생성자이다.
class Person private constructor(val name: String, val age: Int) {
constructor(name: String) : this(name, 0) {
println("Secondary constructor called with name: $name")
}
// private 부 생성자
private constructor(name: String, age: Int, secret: String) : this(name, age) {
println("Secondary constructor called with secret: $secret")
}
companion object {
// private 부 생성자를 사용하는 팩토리 메서드
fun createWithSecret(name: String, age: Int, secret: String): Person {
return Person(name, age, secret)
}
}
}
fun main() {
val person1 = Person("Alice") // 공개된 주 생성자를 사용
val person2 = Person.createWithSecret("Bob", 30, "secret") // 비공개 부 생성자를 사용하는 팩토리 메서드
// val person3 = Person("Charlie", 25, "hidden") // 오류: 비공개 부 생성자에 직접 접근할 수 없음
}
이처럼 부분적으로 외부에 공개할 생성자와 비공개로 할 생성자를 정의할 수 있다.