프로그래밍 언어/코틀린

코틀린 13. 생성자

닉네임못짓는사람 2020. 12. 24. 18:46
반응형

이번 글에서는 클래스의 생성자에 대해서 알아보도록 하겠습니다.

생성자


저번 글에서 클래스의 기본적인 구조에 대해서 알아봤었습니다.

생성자는 클래스의 인스턴스를 생성할 때 호출하게 되는 특수한 함수를 말합니다.

따라서 클래스를 통해 객체를 생성할 때에 무조건 이 생성자를 호출하여 내부의 코드를 실행하게 되어있으며,

이를 통해 객체 생성 시 수행해야 하는 코드들을 이곳에 입력하게 됩니다.

 

예를 들어 baby라는 클래스를 만들어서 객체를 생성한다고 생각해봅시다.

이때 생성자를 사용해서 아기가 태어날 때 "응애"하며 우는 텍스트가 가장 먼저 출력되도록 할 수 있습니다.

 

그렇다면 생성자는 어떻게 사용하는 걸까요?

먼저, 클래스의 속성들만 초기화할 때에는 다음과 같이 사용할 수 있습니다.

fun main() {
    var st1 = student(175, 75)
    var st2 = student(180, 80)
    
    st1.printInfo()
    st2.printInfo()
}

class student(var height: Int, var weight: Int){
    fun printInfo(){
        println("학생의 키: ${this.height}, 학생의 몸무게: ${this.weight}")
    }
}

위의 코드에서 학생의 키와 몸무게를 생성자를 통해 입력받아 저장해놓는 클래스를 만들었습니다.

이때 생성자는 student이하 괄호 안에 있는 코드들을 이야기합니다.

 

마치 함수에서 parameter를 선언하는 것과 같이 클래스 내의 속성들을 선언하여

객체 생성시에 이 생성자에 argument를 주어 객체의 속성들을 초기화하는 것입니다.

 

또한 저번 글에 이어서 this라는 키워드가 등장했는데, this는 객체 내부에서

객체 자신의 속성이나 함수를 호출하기 위해 사용되는 키워드입니다.

 

이렇게 생성자를 통해 클래스의 속성을 초기화시켜봤는데,

이런 상태로는 속성의 초기화는 가능하겠지만, 이외에 다른 코드를 실행하기는 불가능합니다.

때문에 위와 같은 형태가 아닌 새롭게 init이라는 함수를 구현하여 수행하도록 할 수 있습니다.

 

init은 생성자를 통해 객체가 생성될 때 자동적으로 수행되는 함수를 말합니다.

바로 코드를 통해서 확인해봅시다.

fun main() {
    var ba1 = baby()
}

class baby(){
    init{
        println("응애")
    }
}

init의 특징은 parameter나 반환값이 없는 특수한 함수로, 생성자와 함께 호출되어 내부의 코드만 실행합니다.

또한 우리는 위에서 생성자에서 아무런 작업도 하지 않았지만, 그래도 자동적으로 init과 호출되는 것을 볼 수 있습니다.

 

그런데, 이렇게 생성자를 통해서 클래스의 속성을 초기화할 때 다음과 같은 상황이 발생할 수 있습니다.

예를 들어 위의 student클래스에 나이를 뜻하는 age라는 속성을 추가한다고 생각해봅시다.

class student(var age: Int, var height: Int, var weight: Int){
    fun printInfo(){
        println("학생의 키: ${this.height}, 학생의 몸무게: ${this.weight}")
    }
}

이때 student클래스의 인스턴스를 100개 생성한다고 했을 때 80개 정도의 age는 18이고,

나머지 20개는 17또는 19로 초기화하려고 한다면 어떻게 할까요?

 

일단, 그냥 일일이 모든 객체에 age를 지정해주는 방법을 사용할 수 있습니다.

하지만 이렇게 조금 비효율적이라는 생각이 들지 않나요?

때문에 코틀린에서는 '보조생성자'라는 것을 지원하고 있습니다.

보조생성자


보조생성자는 말 그대로 생성자를 보조하는 역할을 하는데요.

말로 설명하기 전에 코드부터 확인해보도록 합시다.

fun main() {
    var st1 = student(17, 175, 75)
    var st2 = student(180, 70)
    var st3 = student(19, 173, 76)
}

class student(var age: Int, var height: Int, var weight: Int){
    init{
        println("학생의 나이: ${this.age}, 학생의 키: ${this.height}, 학생의 몸무게: ${this.weight}")
    }
    
    constructor(height: Int, weight: Int) : this(18, height, weight){
        
    }
}

위의 student클래스를 이처럼 바꿔보았는데, 편의상 printInfo함수는 init함수로 옮겨두었습니다.

먼저, 보조생성자를 만드는 방법은 constructor라는 키워드를 사용해야 합니다.

그리고 constructor이하 괄호 안에 기본생성자와는 다른 형태의 parameter를 지정해줍니다.

이때 중요한 점은 여기서는 var을 붙이지 않는다는 점입니다.

 

parameter를 추가했다면, 보조생성자를 통해서 클래스의 기본 생성자를 호출해야 하는데, 때문에 '보조생성자'인거죠.

기본생성자를 호출하는 방법은 콜론(:)을 입력하고, this키워드를 사용한 뒤 이하 괄호 안에

기본생성자에 들어갈 argument를 입력해주시면 됩니다.

 

이렇게 해주시면 객체 생성 시에 입력받는 argument의 개수에 따라서 기본생성자와 보조생성자를 나눠서 호출할 수 있습니다.

위에서는 argument를 3개 모두 입력했을 경우 기본생성자를 호출하도록 되어있으며,

키와 몸무게만 입력했을 경우 보조생성자를 통해 age는 18로 입력되도록 만들었습니다.

 

이러한 보조생성자는 하나만 만들 수 있는 것이 아니고 '오버로딩'을 통해 여러 개를 만들 수도 있습니다.

오버로딩에 대해서는 추후에 설명할 테니 일단은 넘어가도록 합시다.

fun main() {
    var st1 = student(17, 175, 75)
    var st2 = student(180, 70)
    var st3 = student(178)
}

class student(var age: Int, var height: Int, var weight: Int){
    init{
        println("학생의 나이: ${this.age}, 학생의 키: ${this.height}, 학생의 몸무게: ${this.weight}")
    }
    
    constructor(height: Int, weight: Int) : this(18, height, weight){
        
    }
    
    constructor(height: Int) : this(19, height, 70){
        
    }
}

위와 같이 parameter를 키와 몸무게만 받는 보조생성자와, 키만 받는 보조생성자를 두 개 생성할 수 있습니다.

생성자는 객체를 생성할 때 가장 처음 실행되는 부분으로, 유용하게 사용되니 잘 알아두시길 바랍니다.

 

이번 글은 이 정도로 마치도록 하겠습니다.

감사합니다.

 

반응형

'프로그래밍 언어 > 코틀린' 카테고리의 다른 글

코틀린 15. 오버라이딩과 오버로딩  (0) 2020.12.26
코트린 14. 상속  (0) 2020.12.25
코틀린 12. 클래스  (0) 2020.12.24
코틀린 11. 입출력  (0) 2020.12.23
코틀린 10. 흐름제어  (0) 2020.12.23