[코틀린] 가시성 변경자

hee09·2021년 11월 17일
1
post-thumbnail

가시성 변경자 : 기본적으로 공개(public)

변경자클래스 멤버최상위 선언
public모든 곳에서 볼 수 있다모든 곳에서 볼 수 있다
internal같은 모듈 안에서만 볼 수 있다같은 모듈 안에서만 볼 수 있다
protected하위 클래스 안에서만 볼 수 있다(최상위 선언에 적용할 수 없음)
private같은 클래스 안에서만 볼 수 있다같은 파일 안에서만 볼 수 있다

가시성 변경자는 코드 기반에 있는 선언에 대한 클래스 외부 접근을 제어합니다. 어떤 클래스의 구현에 대한 접근을 제한함으로써 그 클래스에 의존하는 외부 코드를 깨지 않고도 클래스 내부 구현을 변경할 수 있습니다.

  • 코틀린의 기본 가시성은 자바와 다른데, 아무 변경자도 없는 경우 선언은 모두 공개(pubilc)됩니다.

  • 자바의 기본 가시성인 패키지 전용(package-private)은 코틀린에 없습니다. 코틀린은 패키지를 네임스페이스를 관리하는 용도로만 사용하기 때문입니다.

  • 패키지 전용 가시성에 대한 대안으로 코틀린에는 internal이라는 새로운 가시성 변경자가 도입되었습니다. internal은 "모듈 내부 에서만 볼 수 있음"이라는 뜻입니다. 여기서 모듈(module)은 한 번에 한꺼번에 컴파일되는 코틀린 파일들을 의미합니다.

    • 모듈 내부 가시성은 모듈의 구현에 대해 진정한 캡슐화를 제공한다는 장점이 있습니다. 자바에서는 패키지가 같은 클래스를 선언하기만 하면 어떤 프로젝트의 외부에 있는 코드라도 패키지 내부에 있는 패키지 전용 선언에 쉽게 접근할 수 있습니다. 그렇기에 모듈의 캡슐화가 쉽게 깨집니다.
  • 코틀린에서는 최상위 선언에 대해 private 가시성(비공개 가시성)을 허용한다는 점입니다. 그런 최상위 선언에는 클래스, 함수, 프로퍼티 등이 포함됩니다. 비공개 가시성인 최상위 선언은 그 선언이 들어있는 파일 내부에서만 사용할 수 있습니다.

  • 자바에서는 같은 패키지 안에서 protected 멤버에 접근할 수 있지만, 코틀린에서는 그렇지 않다는 점에서 자바와 코틀린의 protected가 다르다는 사실에 유의해야 합니다. protected 멤버는 오직 어떤 클래스나 그 클래스를 상속한 클래스 안에서만 보입니다. 이전에 확장 함수에서 보았듯이 클래스의 확장 함수는 그 클래스의 private이나 protected 멤버에 접근할 수 없습니다.

  • 코틀린에서는 외부 클래스가 내부 클래스(inner)나 중첩 클래스의 private 멤버에 접근할 수 없습니다.


예시

open class Parent {
    // protected로 선언하였기에 자기 자신 또는 하위 클래스에서 사용 가능
    protected open val name = "코틀린"
    // class의 private으로 선언해서 클래스 내에서만 접근 가능
    private val address = "대한민국"
    // 아무런 가시성이 없기에 public에 해당
    open val tel = "00000"
}

// Parent 클래스를 상속 받음
class Child: Parent() {
    fun call() {
        // protected 멤버에 접근
        println(name)
        // public 멤버에 접근
        println(tel)
        // private 멤버에 접근 불가능(에러)
        println(address)
    }
}

fun main() {
    val parent: Parent = Parent()
    // protected 멤버에 접근 불가능(에러)
    println(parent.name)
    // private 멤버에 접근 불가능(에러)
    println(parent.address)
    // public 멤버에 접근 가능
    println(parent.tel)
}

위 예시는 Parent라는 기반 클래스, Child라는 하위 클래스를 선언하고 기반 클래스에 선언된 가시성에 따라서 접근할 수 있는 멤버를 확인하기 위해 작성한 코드입니다. 아무것도 선언하지 않은 tel은 public이기에 모두 접근이 가능하고, 클래스 안의 private 멤버인 address는 클래스 안에서만 접근이 가능하기에 그 밖에서 접근하려면 오류가 발생합니다. 그리고 protected 가시성을 가진 name은 자기 자신과 하위 클래스에서는 접근 가능하지만 그 밖에서는 접근이 불가능하기에 main()에서 접근하면 오류가 발생합니다.


profile
되새기기 위해 기록

0개의 댓글