기본 생성자
우선 코틀린 클래스의 기본 형태는 다음과 같다.
위 클래스는 아직 생성자가 없다. 만든다면 다음과 같이 만들 수 있다.
일반적으로 코틀린은 자바, C++과는 달리 클래스 선언 부분에서 이름에 괄호를 붙여 생성자를 만들 수 있다. 생성자 한 개만 만든다고 했을 때 위와 같은 형태를 주로 만들 것이다. 이렇게 만든 생성자를 [기본 생성자]라고 한다. 여기까지만 보면 기존 언어와 큰 차이가 없어 보일 수 있다. 그들도 [클래스 이름(인자들)] 같은 형태로 생성자를 만들기는 하니까. 차이는 생성자로부터 받아온 변수를 해당 클래스에서 사용하는 방법에 의해 생긴다.
자바의 경우 생성자로부터 받아온 변수를 해당 클래스에서 사용할 때 생성자 내에서 [this.클래스변수 = 매개변수] 같은 형식으로 받아올 수 있다. 하지만 코틀린은 생성자 영역이 없어서 이렇게 할 수가 없다. 즉 [this.클래스변수*= 매개변수]를 쓸 수가 없는 것이다!
어떡하지? 할당을 못하면 생성자로부터 넘어온 데이터를 쓸 수 없다. 이렇게 단념할 준비를 해야하나... 하지만 걱정하지 않아도 된다. 프로그래밍 언어 만드는 사람들은 상당히 똑똑해서 이런 상황에 대비해 미리 만들어 둔 것이 있으니 바로 init이다.
초기화 영역 init
자바에서는 생성자에서 바로 필드들을 초기화할 수 있다. 하지만 코틀린을 별도의 생성자 영역이 없기 때문에 init 영역에서 초기화해주어야 한다. 말로하는 것보다 보는 것이 이해가 빠를 것이다.
init 안에서는 자바처럼 [this.클래스변수= 매개변수]를 얼마든지 할 수 있다. 어메이징!! 그런데 이렇게 항상 init을 만들어줘야 할까 하는 의문이 들기 시작하지 않는가?(아닐 거라 생각한다.) 그런 생각이 든 여러분들을 위해 코틀린 제작자들은 재미난 기능을 만들었다.
인자=변수 생성자
인자=변수** 생성자가 무엇인지 설명하기 전에 우선 코드부터 보고 가자.
감이 잡혔을지 모르겠다. 그렇다! init을 쓰지 않아도 생성자의 인자를 바로 클래스 내에서 쓸 수 있는 것이다. 즉 생성자 인자임과 동시에 클래스 변수이기 때문에 init 영역의 초기화가 없어도 외부에서 받아온 값을 그대로 쓸 수 있는 것이다. 정말 편하지 않은가?! 누가 만들었는지 오늘 저녁은 꼭 치킨 드세요!!(채식주의자면 최고급 양배추를!)
부수 생성자 constructor
지금까지 잘 따라 왔다면 문득 그런 생각이 들었을 것이다.
음..근데 생성자를 꼭 클래스 이름 옆에 생성할 수 밖에 없나? 그러면 여러 개 만들 때는 어떡하지??
아주 훌륭한 생각이다. 이런 생각을 하신 여러분들이라면 오늘 저녁은 꼭 치킨을 드시길 바란다. 물론 가능하다. 생성자를 만드는 방법이 저것만 있는 것이 아니다. constructor라는 키워드를 사용하면 된다.
흡사 자바의 생성자와 비슷하다. 실제로 자바처럼 constructor 영역에서 매개 변수 초기화가 가능하다. 즉 [this.클래스변수= 매개변수]를 할 수 있다.
또한 constructor는 여러개 사용할 수 있다. 즉 기타 언어들과 마찬가지로 생성자 여러개 생성하는 것이 가능하다. 하지만 그 전에 주의할 사항이 있다. 다음 코드를 봐보도록 하자.
뜬금없는 에러에 당황했을 수 있지만 괜찮다. 다음과 같이 수정하면 에러는 사라진다.
에러가 사라진 이유를 이해하기 위해선 ‘상속'의 개념을 알고 있어야 하는데 여기서는 설명하지 않겠다. 아무튼 왜 상속이 필요한가 하면 constructor로부터 생성된 생성자는 ‘기본 생성자’를 ‘상속' 받아야 한다. 그렇기 때문에 기본 생성자를 상속받고 난 이후에는 에러가 사라진 것이다. 물론 기본 생성자를 상속 받는 것이니 constructor로 만든 생성자들은 반드시 기본 생성자가 갖고 있는 인자들을 갖고 있어야 한다. 그렇지 않으면 또 에러의 늪으로..
이쯤되니 constructor 여러 개를 만드는 것이 두렵기 시작한다. 기본 생성자가 갖고 있는 것을 꼭 상속해야하는 부담도 있고 다양하게 생성자를 쓰고 싶은데 자꾸 상속에 늪에 빠진다. 하지만 걱정할 것 없다. 우리에겐 기본생성자가 없는 클래스가 있으니까..!
위 클래스는 사실상 기본 생성자가 없는 형태다. 물론 호출할 때는 Handsome09()같이 ()를 붙이긴 하지만 기본 생성자로 인자가 없는 생성자를 갖는 클래스와는 엄연히 다르다. 아무튼 기본생성자가 없다는 것은 곧 constructor가 상속해야 할 생성자가 없다는 것이다. 즉 이런 클래스에서는 constructor를 매우 자유롭게 만들어줄 수 있다.
constructor의 주의사항
constructor사용에 있어 주의사항이 있다. constructor로 생성한 생성자는 기본생성자가 아니다. 그래서 [인자 = 변수 생성자]같은 형태로 쓸 수는 없다. 그렇기 때문에 생성자 영역에서 매개변수를 클래스변수에 할당을 해주도록 하자.
까다롭다..
여기까지 잘 보셨다면 느껴지겠지만 일반적 객체지향 언어와는 달리 코틀린은 생성자 사용이 약간은 까다롭다(했던 말 또 하는 것 같은데 맞다). 하지만 사용에 익숙해지면 다른 언어보다 쓰는 게 재밌을 것이다. 특히 [인자 = 변수 생성자] 활용을 잘 하는 것이 더 간결하고 기능적인 프로그래밍에 도움이 될 것이라 생각한다. 생성자를 다양하게 활용하는 만큼 코틀린은 다양한 클래스 형태를 제공한다. 다음에는 코틀린의 다양한 클래스에 대해 알아보고자 한다. 그럼 이만~
주석
*사실 코틀린에서는 클래스변수라는 말보다는 프로퍼티라는 말이 더 옳다. 하지만 본 글에서는 이해를 돕기 위해 클래스변수라는 말을 그대로 사용하였다.
**이해를 돕기 위해 지어낸 말이다. 실제로 이런 형태의 생성자가 무엇인지 지칭하는 말이 있는지는 아직 알아내진 못했다.
***사실 엄밀히 말해서 [this.클래스변수*= 매개변수]를 하지 않고도 클래스 변수에 매개변수를 대입할 수는 있다.