본문 바로가기

Kotlin

공식 문서로 배우는 코틀린 - 18. Visibility modifiers

열여덟 번째, 가시성 수정자입니다.

 

클래스, 객체, 인터페이스, 생성자, 함수, 프로퍼티와 해당 세터 모두는 가시성 수정자(visibility modifier)를 가질 수 있습니다.

 

Kotlin에는 다음과 같은 네 개의 가시성 수정자가 있습니다.

  • private
  • protected
  • internal
  • public

기본 가시성은 public입니다.

 

여기서는 범위(scope) 유형에 따라 수정자가 어떻게 다르게 적용되는지 알아 보겠습니다.

 

패키지

함수, 프로퍼티, 클래스, 객체, 인터페이스는 패키지안의 최상위 수준(top-level)에 직접적으로 선언될 수 있습니다.

// file name: example.kt
package foo

fun baz() { ... }
class Bar { ... }

 

  • 가시성 수정자를 사용하지 않으면 public이 기본적으로 사용되는데, 이는 해당 선언이 모든 곳에서 보인다는 뜻입니다.
  • 선언을 private으로 지정하면, 해당 선언을 담고 있는 파일 내에서만 보입니다.
  • internal로 지정하면, 같은 모듈 안에서는 어디에서든지 보인다는 뜻입니다.
  • protected 수정자는 최상위 수준 선언에는 사용할 수 없습니다.

※ 볼 수 있는 최상위 수준의 선언을 다른 패키지에서 사용할 때는 해당 선언을 임포트합니다.

 

// file name: example.kt
package foo

private fun foo() { ... } // example.kt 안에서만 보입니다.

public var bar: Int = 5 // 프로퍼티는 모든 곳에서 보입니다.
    private set         // 세터는 이 파일 안에서만 보입니다.

internal val baz = 6    // 같은 모듈 안에서만 보입니다.

 

클래스 멤버

클래스 내에 선언된 멤버에 대해서는 다음과 같습니다.

  • private : 해당 멤버(와 그 멤버에 속하는 모든 멤버)가 클래스 내에서만 보입니다.
  • protected : private하고 동일하지만 하위 타입에서도 보입니다.
  • internal : 같은 모듈 내에서 해당 클래스를 볼 수 있는 클라이언트는 해당 클래스의 internal 멤버도 볼 수 있습니다.
  • public : 특정 클래스를 볼 수 있는 클라이언트는 해당 클래스의 public 멤버를 모두 볼 수 있습니다.

※ 코틀린에서는 외부 클래스가 내부 클래스의 private 멤버를 볼 수 없습니다.

 

protected나 internal 멤버를 오버라이딩하고 명시적으로 가시성 수정자를 지정하지 않으면, 오버라이딩 멤버도 원래 멤버와 동일한 가시성을 갖습니다.

 

open class Outer {
    private val a = 1
    protected open val b = 2
    internal open val c = 3
    val d = 4  // public by default

    protected class Nested {
        public val e: Int = 5
    }
}

class Subclass : Outer() {
    // a is not visible
    // b, c and d are visible
    // Nested and e are visible

    override val b = 5   // 'b' is protected
    override val c = 7   // 'c' is internal
}

class Unrelated(o: Outer) {
    // o.a, o.b are not visible
    // o.c and o.d are visible (same module)
    // Outer.Nested is not visible, and Nested::e is not visible either
}

 

생성자

클래스의 주 생성자에 가시성 수정자를 지정할 때는 다음의 구문을 따릅니다.

※ 명시적인 constructor 키워드를 추가하는 것도 필요합니다.

class C private constructor(a: Int) { ... }

 

이 생성자는 private입니다. 기본적으로 모든 생성자는 public인데, 이는 실질적으로 클래스가 보이는 모든 곳에서 생성자도 보이게 됩니다(이 말은 internal 클래스의 생성자는 오로지 같은 모듈 내에서만 보인다는 뜻입니다).

 

봉인된 클래스(sealed class)에서 생성자는 기본적으로 protected입니다. 더 자세한 사항은 봉인된 클래스를 참고하세요.

 

지역 선언

지역 변수/함수/클래스는 가시성 수정자를 가질 수 없습니다.

 

모듈

internal 가시성 수정자는 같은 모듈 내에서만 보인다는 뜻입니다. 보다 구체적으로, 모듈은 함께 컴파일되는 코틀린 파일들의 집합입니다. 예를 들면 다음과 같습니다.

  • IntelliJ IDEA 모듈
  • 메이븐(maven) 모듈
  • 그레이들 소스셋(test 소스 셋이 main의 내부 선언을 접근하는 것은 예외)
  • <kotlinc> 앤트(Ant) 태스크 한 번의 호출로 컴파일 되는 파일 집합