엔지니어 규의 IT 프로그래밍 다이어리

[Kotlin]8. 클래스의 생성자 본문

프로그래밍 언어/코틀린

[Kotlin]8. 클래스의 생성자

엔지니어 규 2022. 5. 9. 23:33
728x90

생성자(Constructor)

 

생성자란 뭘까? 

 

새로운 인스턴스를 만들기 위해 호출하는 특수한 함수이며, 생성자를 생성하면 클래스의 인스턴스를 만들어 반환 받을 수 있다. 

 

생성자는 인스턴스의 속성을 초기화 하며, 인스턴스 생성시 구문을 수행 한다.

 

당최 무슨 말인지 하나도 이해가 가지 않을 수 있다.

 

우선 인스턴스의 속성을 초기화 한다는 것을 알아보자.

 

다음 코드를 보자.

class PersonA{}
 
class PersonB(){}
 
class PersonC(var name : String){}
 
class PersonD(var name: String, birthyear: Int){}
cs

차례로 생성자가 없는 class, 인자가 없는 생성자, 인자가 1개인 생성자, 인자가 2개인 생성자 이다.

 

이처럼 코틀린은 괄호를 클래스 이름 뒤에 붙여서 생성자를 만들 수 있다. 

 

여기서 괄호안의 인자들은 클래스로부터 생선된 인스턴스 의 속성을 초기화(새로 할당한다는 의미) 시켜준다.

 

이렇게 만들어진 생성자를 기본생성자 라고 한다. 

 

 

public class Person {
    String name;
    int number;
 
    public Person(){
    }
 
    public Person(String name){
        this.name = name;
    }
 
    public Person(String name, int number){
        this.name = name;
        this.number = number;
    }
}
cs

자바의 경우 생성자로부터 받아온 변수를 해당 클래스에서 사용할 때 생성자 내에서 [this.클래스변수 = 매개변수] 같은 형식으로 받아온다.

 

여기서 this.name = name; 에서 앞의 this.name 은 필드의 String name; 에 할당이 되며,

 

= name 은 public Person(String name) 에서 매개변수이다. 

 

person = new Person("박재범")   으로 main 메소드에서 생성자를 호출하면 "박재범" 은 매개변수 로 할당이되고

 

할당된 매개변수는 다시 this.name 에 할당이 되며, this.name 은 필드의 name에 할당된다.

 

 

 

하지만 코틀린에서는 생성자에서 받아온 변수를 해당클래스에서 사용할때 별다른 조작없이 바로 사용이 가능하다.(!?)

class Person(var name: String, var birthyear: Int){
    fun introduce(){
        return println("안녕하세요 저의 이름은 ${name} 이고  ${birthyear} 년생입니다.")
    }
}
cs

여기서 Person class 의 생성자에서 받아온 변수를 바로 구문내에서 사용 가능하다. 

[생성자 인자 = 클래스 변수] 처럼 사용이 가능하다.

 

엄청난 혁신이 아닐 수 없다.

 

 

 

다음으로 인스턴스 생성시 구문 수행 에 대해 알아보자.

인스턴스 생성시 특정 구문을 수행하기 위해서는 init 이라는 함수를 사용하면 된다.

 

init : 패러미터나 반환형이 없는 특수한 함수로, 생성자를 통해 인스턴스가 만들어 질 때 호출되는 함수이다.

1
2
3
4
5
6
7
8
9
10
fun main(){
    var a = Person("박보영",1994) // 1994년생 박보영님이 생성되었습니다.
    var b = Person("김종국",1990) // 1990년생 김종국님이 생성되었습니다.
    var c = Person("이나영",1998) // 1998년생 이나영님이 생성되었습니다.
}
class Person(var name: String, val birthyear: Int){
    init{
        println("${this.birthyear}년생 ${this.name}님이 생성되었습니다.")
    }
}
cs

여기서 this 는 인스턴스 자신의 속성이나 함수를 호출하기 위해 클래스 내부에서 사용되는 키워드 이다.

 

main 함수 내부에 별다른 수행 구문이 없어도 인스턴스의 생성을 통해 init이 호출되어

 

세개의 인스턴스에 넣은 속성들이 출력되는 것을 볼 수 있다.

 

이러한 생성자를 사용 할때 항상 모든 속성을 수동으로 초기화 하는 것이 비 효율적인 경우도 있다.

 

예를 들어 Person 클래스를 사용하여 100명의 사람이 가진 이름과 태어난 년도를 인스턴스로 만든다고 생각해 보자.

 

이때 1997년생에 95명이라면 당연히 1997년생을 '기본값'으로 만들 수 있는 방법이 있다면 좋을것이다.

 

이때는 보조 생성자 라는 것을 사용한다.

 

기본 생성자 : 클래스를 만들 때 기본으로 선언

보조 생성자 : 필요에 따라 추가적으로 선언, 기본생성자와 다른 형태의 생성자를 제공하여 인스턴스 생성시 편의를 제공

 

보조생성자는 constructor 라는 키워드를 사용한다.

 

다음의 예문을 보자

 

fun main() {
 
    var d = Person("김태연")
    var e = Person("박재범")
 
}
 
class Person(var name: String, var birthyear: Int){
 
    init{
        println("${birthyear}년생 ${name}님이 생성되었습니다.")
    }
 
    constructor(name: String) : this(name,1997){
        println("보조생성자가 사용되었습니다.")
    }
 
}
cs

위 구문을 실행하면

1997년생 김태연님이 생성되었습니다.
보조생성자가 사용되었습니다.
1997년생 박재범님이 생성되었습니다.
보조생성자가 사용되었습니다.

 

이런결과가 나온다.

 

여기서 보조생성자 를 생성할 때는 반드시 기본생성자를 통해 속성을 초기화해야만 한다.

 

보조 생성자인 [constructor(name: String)] 는 기본생성자를 [: this(name,1997)] 를 통해 호출한다.

 

여기서 this() 에는 기본생성자가 필요로 하는 parameter를 넘겨준다. (name,1990)

 

이해를 돕기위해 또다른 소스코드를 공부해보자

class Animal(val nLeg:Int, val color:String) {
    var name:String = "Tom"
    init {
        println("=== Primary Init block ===")
        println("nLeg: $nLeg, color: $color, name: $name")
        // Do something!!
    }
 
    constructor(_nLeg:Int, _color:String, _name:String) : this(_nLeg, _color) {
        println("=== Secondary constructor start ===")
        this.name = _name
        println("=== Secondary constructor end ===")
    }
 
    fun eat(something:String) {
        println("Eat $something")
    }
 
    fun cry() {
        println("Cry!!!")
    }
}
cs

[constructor(_nLeg:Int, _color:String, _name:String)] 는 보조 생성자이며,

 

기본생성자를 [: this(_nLeg, _color)] 를 통해 호출한다.

 

 

 

 

이처럼 기본생성자와 보조생성자는 클래스를 사용하는 사람에게 다양한 방법으로 

 

인스턴스를 생성하는 방법을 제시함으로써 편리함을 제공한다.

 

 

 

 

 

 

 

728x90
Comments