관리 메뉴

나만을 위한 블로그

[Kotlin] companion object(동반 객체)란? 본문

개인 공부/Kotlin

[Kotlin] companion object(동반 객체)란?

참깨빵위에참깨빵_ 2022. 1. 31. 16:32
728x90
반응형

자바에 static 변수(필드), 메서드가 존재하듯 코틀린에서도 정적 변수와 함수가 존재한다.
그러나 코틀린의 문법 특성 상 이것들을 클래스 안에 둘 수는 없고, 코틀린에는 static이라는 키워드가 존재하지 않는다. 그럼 어떻게 사용할까? 이 때를 위해 존재하는 것이 companion object라는 것이다. 사용법은 아래와 같다.
 

class TestClass {
    companion object {
        val name = "TestClass"
        fun method() {}
    }
}

fun main() {
    TestClass.name
    TestClass.Companion.name
    TestClass.method()
    TestClass.Companion.method()
}

 
인텔리제이에서 위 코드를 복붙하고 보면 Companion이 짙은 검회색으로 보이며 생략 가능하다고 알려준다.
IDE가 말한 대로 Companion은 생략 가능한 키워드다. 그러나 이것은 companion object에 이름이 있다면 Companion이라고 쓰면 안 된다.
무슨 말이냐면 코틀린에선 companion object 뒤에 이름을 써서 companion object의 이름을 지어줄 수도 있다. 아래는 위의 코드에서 companion object에 test라는 이름을 붙여준 경우를 보여주는 예시다.
 

class TestClass {
    companion object Test {
        val name = "TestClass"
        fun method() {}
    }
}

fun main() {
    TestClass.name
    TestClass.Test.name
    TestClass.method()
    TestClass.Test.method()
}

 
Test라는 이름이 붙었기 때문에 main()에서 Test 대신 예전처럼 Companion을 쓰면 컴파일 에러가 발생하는 걸 볼 수 있다.
그럼 이 companion object를 하나가 아니라 여러 개 쓸 수도 있지 않을까? 한번 해 보자.
 

 
인텔리제이가 바로 컴파일 에러를 내면서 입구컷하는 걸 볼 수 있다. 저 메시지가 말하는 대로 하나의 클래스에는 오직 하나의 companion object만 존재할 수 있기 때문에 2번째 companion object를 만들었을 때 곧바로 컴파일 에러가 발생한다.
여기까지 읽은 사람들 중 '아몰랑 어쨌든 자바의 static과 코틀린의 companion object는 대충 같은 거겠지?' 라고 생각하는 사람이 있을 수 있다. 그러나 이름에서 알 수 있듯 companion object는 엄연한 "객체"다. 때문에 자바의 static과 다른 성질을 갖고 있다. 이것에 대해서는 아래의 블로그가 이해하기 쉽게 설명하고 있으니 참고하면 좋을 것 같다.
 
https://www.bsidesoft.com/8187

[kotlin] Companion Object (1) - 자바의 static과 같은 것인가? - Bsidesoft co.

개요 코틀린(Kotlin)의 Companion object는 단순히 자바(Java)의 static 키워드를 대체하기 위해서 탄생했을까요? 이 갑작스러운 질문은 코틀린에서 왜 static을 안 쓰게 되었는지 이해하는 데 큰 도움이 될

www.bsidesoft.com

 
추가로 아래의 예시는 companion object를 써서 팩토리 패턴을 구현한 예시다.
 

class User private constructor(val name: String, val registerTime: Long) {
    companion object {
        // companion object는 클래스 안에 존재하므로 private 선언된 생성자에 접근 가능하다
        fun create(name: String): User {
            return User(name, System.currentTimeMillis())
        }
    }
}

 

반응형
Comments