본문 바로가기

Kotlin(코틀린)

Kotlin(코틀린) > 주생성자와 보조생성자

코틀린을 처음 접하게 되었는데 자바랑 비슷한 점도 많았지만 다른 점이 많아서 이해하기 어려움을 겪었다.

 

Kotlin(코틀린) 카테고리에서는 기초적인 문법 내용과 관련 실습을 포스팅 해보려고 한다.

첫 번째 주제로 주생성자와 보조생성자에 대하여 알아보자.

 

주생성자란?

클래스를 초기화하는 데 사용되며, 클래스의 속성을 정의하고 초기화하는 데에 사용된다. 사용 시 클래스 선언 부분에 포함한다.

 

주생성자는 클래스 이름 뒤에 온다. 일반적인 꼴은 다음과 같다.

 

class User(name: String, count: Int) {
   init {
      println("i am init......")
   }
}
fun main() {
   val user = User("kkang", 10)
}
--- 실행 결과 ---
i am init......

 

주생성자 선언은 필수는 아니며 한 클래스에 하나만 가능하다. 

원래 생성자 선언 키워드는 constructor 키워드이지만 생략이 가능하다.(ex. class User constructor() { } )

만약 주생성자가 없다면 constructor 키워드와 () 모두 생략 가능하다.

주생성자의 본문에는 init 영역이 있다. 객체를 생성할 때 자동으로 가장 먼저 실행되는 영역이라고 생각하면 된다.

주생성자의 본문을 구현할 경우에는 위에 있는 예제 처럼 init을 반드시 선언하여 그 영역 안에 함수를 구현하면 될 것이다.

 

여기서 주의할 점이 한 가지 있다. 만약에 생성자의 매개변수를 다른 멤버 함수에서 공유하려면 한가지 키워드를 선언해줘야 한다. 그것은 바로 매개변수 앞에 var이나 val 키워드를 써줘야한다.(클래스의 멤버 변수로 선언하여 접근)

간단해 보이지만 그만큼 실수할 확률이 크다고 생각한다. 꼭 기억해두자. 다음은 var이나 val 키워드를 써주어, 생성자의 매개변수를 클래스의 멤버 변수로 선언한 예제 코드이다.

class User(val name: String, val ount: Int) {
   fun someFun() {
      println("name: $name, count: $count") // 성공
   }
}
fun main() {
   val user = User("kkang", 10)
   user.someFun()
}
--- 실행 결과 ---
name: kkang, count: 10

 

 

 

보조생성자란?

주생성자와는 달리 추가적인 초기화 로직을 제공하거나, 다양한 방법으로 클래스를 초기화할 수 있는 기능을 제공한다. 선언 시 클래스 본문에 포함한다.

 

보조생성자는 주생성자와 다르게 여러 개를 정의할 수 있으며, 각각의 보조생성자는 다른 파라미터의 타입과 개수를 가져야 한다. 이는 자바와 같다. 다음은 보조 생성자 선언 예제 코드이다.

class User {
   constructor(name: String) {
      println("constructor(name: String) call...")
   }
   constructor(name: String, count: Int) {
      println("constructor(name: String, count: Int) call...")
   }
}
fun main() {
   val user1 = User("kkang")
   val user2 = User("kkang", 10)
}

 

부생성자는 클래스의 본문에 constructor 키워드로 선언하는 함수이며 이는 생략 불가능하다.

객체 생성 시 생성 방법에 따라 자동으로 구분하여 호출한다.

 

코틀린의 생성자 호출순서는: 주생성자 - init블록 - 부생성자이다.

 

부생성자를 사용할 때에도 주의할 점이 있는데, 부생성자로 객체를 생성할 때 클래스 내에 주 생성자가 있다면 this() 구문을 이용해 주생성자를 호출해야 한다. 부생성자로 객체를 생성할 때 주생성자가 함께 호출된다. 부생성자만 선언했다면 연결할 필요는 없다. 만약 주생성자가 존재하고 여러 개의 부생성자가 있다면 부생성자간에 호출이 가능하다. 여기서 주의할 점은 부생성자로 객체를 생성하는 경우에는 어떤 방식으로든 주생성자를 호출해야 한다. 이는 중복되는 코드는 주생성자에 구현하게 하려는 의도가 있다. 다음은 부생성자가 여러 개일 때 생성자를 연결하는 예제 코드이다.

 

class User(name: String) {
   constructor(name: String, count: Int): this(name) { // 주생성자 호출
      ... 생략 ...
   }
   constructor(name: String, count: Int, email: String): this(name, count) { // 위의 부생성자 호출
      ... 생략 ...
   }
}
fun main() {
   val user = User("kkang", 10, "a@a.com")
}

 

키워드 하나로 오류가 발생할 수 있으므로, 꼼꼼한 학습이 필요하다고 생각한다.

다음 포스팅은 주생성자와 부생성자 관련 간단한 실습을 하려고 한다.