코틀린은 주생성자(primary constructor)와 부생성자(secondary constructor)로 구분합니다.
초기화 블럭을 통해 초기화 로직을 추가할 수도 있습니다.
- 주 생성자 : 주로 사용하는 간략한 생성자로, 클래스 본문 밖에서 정의
- 부 생성자 : 클래스 본문 안에서 정의
주 생성자
클래스 초기화: 주생성자와 초기화 블록
class User(val nickname: String)
이렇게 클래스 이름 뒤에 오는 괄호로 둘러싸인 코드를 주 생성자(primary constructor)라고 부릅니다.
사실, 괄호 앞에 constructor keyword 가 생략되었습니다.
주 생성자는 생성자 파라미터를 지정하고, 그 생성자 파라미터에 의해 초기화되는 프로퍼티를 정의하는 두 가지 목적에 쓰입니다.
위의 주 생성자는 아래와 같이 변환됩니다.
class User constructor(_nickname:String){ // 파라미터가 하나만 있는 주 생성자
val nickname: String //nickname 이라는 프로퍼티, 초기화 하지 않았기 때문에 아래 init 블럭의 초기화 구문이 없으면 error 발생
init {
nickname = _nickname
}
}
constructor : 주 생성자나 부 생성자 정의를 시작할 때 사용되는 키워드
init : 초기화 블록을 시작. 초기화 블록에는 클래스의 객체가 만들어질 때(인스턴스화 될때) 실행될 초기화 코드가 들어감
init 블럭은 여러개 사용이 가능합니다.
아래와 같이 init은 순서대로 호출이 되면 BBB가 출력이 됩니다.
class User(name: String) {
var name : String
init {
this.name = name
}
init {
this.name = "BBB"
}
}
val user = User("AAA")
println(user.name)
프로퍼티 생성
위의 주 생성자의 파라미터에는 val 키워드가 있습니다.
val 이나 var 키워드를 사용하지 않으면 프로퍼티로 생성이 되지 않습니다.
class User(name : String) //val 이나 var 키워드가 없고, 따로 프로퍼티 선언하지 않았다.
val user = User("James")
print(user.name) //name은 프로퍼티가 아니라 컴파일 에러 발생, 위 생성자의 파라미터에 val or var 키워드가 필요함
생성자 파라미터로 쉽게 프로퍼티를 정의할 수 있게 val/var 키워드를 넣어줍니다.
어떤 클래스를 상속받는경우 부모 클래스의 생성자를 호출해야 합니다.
아래와 같이 User 라는 클래스가 있습니다. 생성자를 따로 정의하지 않았지만, 컴파일러가 자동으로 디폴트 생성자를 만들어 줍니다.
open class User
위 User 클래스를 상속받는 클래스가 부모 생성자를 호출하지 않으면 에러가 발생합니다.
class PenUser(name: String) : User //생성자를 호출하지 않았기 때문에 error
아래와 같이 괄호가 들어간 생성자를 호출해줘야 합니다.
class PenUser(name: String) : User()
interface의 경우는 생성자가 없기 때문에, interface를 상속할 경우 괄호가 없는 이유가 여기에 있습니다.
interface Animal
class Lion : Animal
부 생성자 (secondary constructor)
클래스 블럭 내에 존재하는 생성자로, constructor 키워드를 사용하여 선언합니다.
init 블럭과 같이 있는 경우 init 블럭이 부 생성자보다 먼저 호출됩니다.
--> 이것은 부 생성자만 선언된 경우 초기화 블록은 큰 의미가 없다는 걸 의미합니다.
부 생성자의 매개 변수에는 val, var로 선언할 수 없습니다.
class User(name: String) {
val name : String
var age: Int = 25
var height: Int = 120
init {
this.name = name
}
// 컴파일 에러 : 주생성자가 존재하면 부생성자는 무조건 주생성자에게 직간접적으로 생성을 위임해야 함
// constructor(name: String, age: Int) {
// this.age = age
// }
constructor(name: String, age: Int) : this(name) { //this(name)으로 위임을 위해 주생성자 호출
this.age = age
}
constructor(name: String, age: Int, height: Int) : this(name, age) { //this(name)으로 주생성자에 위임해도 문제 없음
this.age = age
this.height = height
}
}
val user = User("AAA", 12, 155)
'Kotlin' 카테고리의 다른 글
위임자 Delegates (observable, vetoable ) (0) | 2022.05.05 |
---|---|
전개 연산자 * (0) | 2022.05.05 |
생성자 역할을 하는 Factory 함수 (0) | 2022.04.30 |
FrameLayout size/margin 동적변경 (0) | 2022.04.24 |
SubsamplingScaleImageView (0) | 2022.04.23 |