본문 바로가기

Dev/[Kotlin]

[kotlin] 생성자 - 기본 생성자와 보조 생성자(주 생성자와 부 생성자)

반응형

 

INTRO


 

코틀린의 생성자에 대해 알아본다.

 

 


 

 

 

1. 생성자?

- 우선 자바와 비교해보자.

- 비교해보고, 다른 점과 각각의 장 단점에 대해 이야기 해볼것이다.

 

- 자바에서 자주 사용하던 생성자는 아래와 같을 것이다.

class Test {
    String name;
    int age;
  
    public T1(String name, int age){
        this.name = name;
        this.age = age;
    }
}

 

- 코틀린에서 위와 같은 생성자를 만들어보자

class Test {
    var name: String
    var age: Int
    
    constructor(name: String, age: Int) {
    	this.name = name
        this.age = age
    }
}

 

- 여기까지 본다면 비슷하다.

 

- 그러나 코틀린은 아래의 방법으로도 생성자를 만들 수 있다.

- 위 코드와 아래 코드는 같은 역할을 한다.

// Property 초기화와 함께..
class Test(val name:String="", val age:Int=0)

// Property 초기화 없이..
class Test(val name:String, val age:Int)

- 이렇게 클래스를 생성하는 녀석들을 코틀린의 기본 생성자(주 생성자)라고 한다.


 

 

2. constructor?

- 기존 자바에서는 모든 멤버변수를 포함하는 생성자 이외에,

- 추가적인 생성자를 만들 때, public [클래스명] 형태로 만들었다.

- 코틀린에선 constructor 를 앞에 붙여 생성자들을 만든다.

- 이를 보조 생성자 혹은 부 생성자라고 부른다.

 

- 위에서 봤던 코드를 다시 보자.

class Test {
    var name: String
    var age: Int

    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

 

- 코틀린의 기본 생성자 형태로 만들어본다면, 아래와 같이 된다고 했었다.

- 앞으로는 주로 아래와 같은 형태의 생성자를 사용해보자.

- 코틀린이 주는 장점을 최대한 많이 활용해야 하기 때문이다.

class Test(var name:String, var age:Int)

 

- 그런데 여기서, 만약 age 는 항상 고정된 값만 들어가도 되는 상황이라면,

- 인스턴스들을 생성할 때 아래와 같이 같은 값을 매번 넣어줘야한다.

val t1 = Test("김",30)
val t2 = Test("이",30)
val t3 = Test("박",30)
val t4 = Test("최",30)
val t5 = Test("장",30)

 

- 이런 경우에는 보조 생성자를 통해 간단하게 아래와 같이 사용해볼 수 있다.

class T(var name:String, val age:Int){
    // :this()를 통해 넘겨받은 파라미터(name)으로
    // '보조 생성자' 내에서 '기본 생성자'를 호출한다.
    constructor(name: String):this(name,30)
}

 

- 이제 아래와 같이 인스턴스들을 생성하면 된다.

val t1 = T1("김")
val t2 = T1("이")
val t3 = T1("박")
val t4 = T1("최")
val t5 = T1("장")

 

- 코드의 주석을 보면,

- 보조 생성자는 그 자체로 역할을 하진 않고,

- 단순히 파라미터를 받아 주 생성자를 호출하는 용도이다.

- 이를 자바 코드로 변환하면 아래와 같은 형태가 되는 것이다.

- 아래 형태는 자바에서도 자주 사용된다.

public static final class Test {
    private String name;
    private int age;

    public Test(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Test(String name) {
        this(name, 30);
    }
}

 


 

 

3. init{}?

- init{}는 기본 생성자와 함께 호출되는 코드블럭이다.

- 아래처럼 사용하면 된다.

class Test(var name:String, var age:Int){
    init{
        name = "choi"
        age = 30
    }
}

 

- 여기서 한 가지 주의할 점이 있다. 

- init은 '기본 생성자' 와 함께 호출된다고 했다.

- 아래와 같이 인스턴스를 생성된다면,

- 결과는 어떻게 될까? (생성 전? 후?)

class Test(var name:String, var age:Int){
    init{
        name = "choi"
        age = 30
        println("this is init block")
    }
}

fun main() {
    val test1 = Test("park",20)
    println("name : ${test1.name}, age : ${test1.age}")
}

// 결과는..?
// park, 20?
// choi, 30?

- 결과는 아래와 같다.

- init 블럭은 기본 생성자로 프로퍼티에 값을 할당한 후 호출된다.

this is init block
name : choi, age : 30

 

- 자바 코드로 보면 아래와 같다.

- 실수 할 수도 있으니 원리를 잘 이해하고 있어야겠다.

public class Test {
    private String name;
    private int age;

    public Test(String name, int age) {
        this.name = name;
        this.age = age;
        // here is init{} block
        this.name = "choi";
        this.age = 30;
    }
}

 

- 한발 더 나아가서,

- init 블럭에서 프로퍼티들을 초기화 해주는 상황에서

- 보조 생성자가 있는 경우를 생각해보자

 

- 보조 생성자를 통해 인스턴스를 생성했다고해도, 

- 위에서 설명한것처럼 보조 생성자는 결국 파라미터를 가지고 기본 생성자를 호출하므로,

- init 블럭에서 초기화 한 값이 들어갈 것이다.


 

 

 

 

마무리

간단한 예제와 함께 코틀린의 생성자를 알아보았다.

이를 잘 활용한 소스코드들이 많다. 이를 참고하여 좀 더 좋은 코틀린 프로그래머가 되길..

 

 

-퍼가실 때는 출처를 꼭 같이 적어서 올려주세요!

 

반응형

'Dev > [Kotlin]' 카테고리의 다른 글

[Kotlin] 표준 입/출력에 대하여 정리  (0) 2022.09.05