코틀린에서는 public(default)
, internal
, protected
, private
이라는 접근 제어 지시자를 제공합니다.
internal
을 제외한 모든 접근 제어 지시자는 익숙합니다.
자바에서 제공하는 package-private
을 대신한 것이라고도 생각했지만,
코틀린에서의 패키지는 클래스를 나누는 네임스페이스의 역할만 하기 때문에
package-private
이 존재할 수 없습니다.
internal
은 모듈 단위로 접근을 제어하는 것으로 module-private
이라고 부를 수도 있습니다.
그러면 이 모듈의 범위는 어디까지일까요?
모듈이라고 하면 자바 9에 추가된 모듈을 떠올릴 수도 있지만 가장 쉽게 떠오르는 것은
Gradle(그레이들)
프로젝트의 서브 프로젝트입니다.
그레이들을 이용하면 멀티 프로젝트를 구성하여 여러 프로젝트를 하나의 프로젝트 아래에 둘 수 있습니다.
이때 각 프로젝트를 모듈이라고 칭하는데 여기서 internal
로 선언하면 모듈끼리 접근이 안 될 것이라고 생각했습니다.
a-project
ㄴ b-project
ㄴ src
ㄴ com
ㄴ j
ㄴ research
ㄴ B.kt
ㄴ build.gradle.kts
ㄴ c-project
ㄴ src
ㄴ com
ㄴ j
ㄴ research
ㄴ C.kt
ㄴ build.gradle.kts
ㄴ build.gradle.kts
여기서 B
클래스의 접근 제어 지시자가 internal
이라면
B
클래스와 C
클래스는 각각 다른 모듈에 정의되어 있기 때문에
서로 접근을 할 수 없는 형태가 됩니다.
root-project
ㄴ src
ㄴ com
ㄴ j
ㄴ research
ㄴ A.kt
ㄴ B.kt
여기서 A
클래스의 접근 제어 지시자가 internal
이고 B
클래스의 접근 제어 지시자가 public
이라도
같은 모듈 안에 정의되어 있으므로 서로 접근이 가능해야 한다고 생각할 수도 있는데
이는 낮은 접근 수준에서는 높은 접근 수준에 접근할 수 있지만
높은 접근 수준에서는 낮은 접근 수준에 접근할 수 없다는 기본 원리를 해칩니다.
따라서 internal
에서는 public
클래스를 참조할 수 있지만
public
클래스에서는 internal
클래스를 참조할 수 없습니다.
자바에서는 internal
과 같은 접근 제어 지시자가 존재하지 않습니다.
같은 모듈에서는 모두 접근 가능해야 하므로 public
접근 제어 지시자로 변경됩니다.
따라서 코틀린 코드에서는 접근할 수 없었던 클래스가 자바 코드에서는 접근할 수 있게 될 수도 있습니다.
그래서 코틀린 컴파일러는 코틀린 코드를 자바 코드로 변경할 때
internal
클래스의 이름과 메소드 명 등을 알아 볼 수 없게 변경하여
실수로 internal
클래스에 접근하는 것을 막습니다.
Tip!
자바의 protected는 상속 받은 클래스 뿐만 아니라 같은 패키지 내의 클래스도 접근이 가능하지만
코틀린에서는 무조건 상속 받은 클래스만 접근 가능합니다.
internal
로 선언된 클래스는 같은 모듈에서만 접근 가능하며
여기서의 모듈은 Gradle(그레이들)
의 프로젝트 단위 등을 말합니다.