본문 바로가기

Kotlin

[Kotlin] 변수, 함수, 클래스의 접근범위와 접근제한자

프로젝트 내에서 변수나 함수, 클래스의 '공용 범위'를 제어하는 단위인 스코프

스코프 외부에서 스코프 내부로의 접근을 제어하는 접근제한자에 대해 알아보도록 하겠습니다

 

<스코프 scope>

: '범위' 라는 뜻 그대로 언어차원에서 변수나 함수, 클래스 같은 '멤버'들을 서로 공유하여 사용할 수 있는 범위를 지정해 둔 단위

 

스코프가 지정되는 범위는 패키지 내부, 클래스 내부, 함수 내부 등이 있는데요

 

예를 들어 하나의 패키지 안에 하나의 변수, 함수, 클래스가 있다면 그것들은 모두 하나의 스코프 안에 있는 멤버들이지만

 

 

다시 그 안에 있는 함수나 클래스 안에 또 다른 변수나 함수들이 존재한다면

패키지 스코프 안에 또 다른 하위 스코프로 동작하게 됩니다

 

 

 

그렇다면 스코프에 대한 3가지 규칙을 알아보겠습니다

 

1. 스코프 외부에서는 스코프 내부의 멤버를 '참조연산자'로만 참조가 가능

클래스의 멤버를 참조할 때 클래스 외부에서 인스턴스명에 참조 연산자를 사용하여 접근하는 것이 이런 경우입니다

ex) a.eat()

 

그리고 하나의 패키지에서 다른 패키지 내 멤버를 참조 할 때도 import를 사용하거나 직접 참조 연산자를 사용해야 합니다

ex) import com.google.wlrma (com.google.wlrma 안에 있는 모든 멤버를 직접 참조)

com.google.wlrma.A (com.google.wlrma 안에 있는 A라는 이름의 멤버를 참조)

 

 

 

2. 동일 스코프 내에서는 멤버들을 '공유' 가능

파일에 package를 명시하지 않으면 default package가 되는데요

이 상태에서 만드는 모든 멤버들은 같은 패키지 스코프에 포함된다고 생각하시면 됩니다

 

val a = "패키지 스코프"
class B {
    fun print() {
        println(a)
    }
}

fun main() {
    println(a)
    B().print()
}
/* 출력
패키지 스코프
패키지 스코프
*/

 

클래스 B에 a를 출력하는 함수를 만들고,

main 함수 안에서 a를 출력하고, 클래스 B의 인스턴스를 만들어 print 함수를 불러보았습니다

실행해보면 변수 a는 클래스 B나 main 함수에 속해 있지는 않지만

동일한 스코프 내에서 변수를 공유하여 사용할 수 있는 것을 볼 수 있습니다

 

 

 

3. 하위 스코프에서는 상위 스코프의 멤버를 재정의 가능

원래 스코프의 같은 레벨에서는 같은 이름의 멤버를 만들어서는 안됩니다

var a = "hi"

var a = "hello"

이렇게 a라는 변수를 2번 선언하면 conflicting error가 발생합니다

(conflicting declarations : 선언부가 서로 충돌한다는 뜻)

 

하지만 하위 스코프에서는 같은 이름의 멤버를 만들어 사용할 수 있습니다

 

val a = "패키지 스코프"
class B {
    val a = "클래스 스코프"
    
    fun print() {
        println(a)
    }
}

fun main() {
    val a = "함수 스코프"
    println(a)
    B().print()
}
/* 출력
함수 스코프
클래스 스코프
*/

 

main 함수 안에 변수 a를 값을 다르게 하여 만들고 클래스 B 안에도 변수 a를 만들어주었습니다

그리고 실행 결과를 보면 상위 스코프에 있던 변수 a를 참조하지 않고 각각의 스코프에 있는 값을 참조하는 것을 확인할 수 있습니다

 

 

 

위에서 스코프 외부에서 스코프 내부로 접근하려면 참조연산자를 사용한다고 했었는데요,

그와 비슷하지만 다른 접근제한자에 대해 알아보도록 하겠습니다

 

 

 

 

 

<접근제한자 Access Modifier>

접근제한자는 스코프 외부에서 스코프 내부에 접근할 때 그 권한을 '개발자가 제어'할 수 있는 기능입니다

접근제한자에는 public, internal, private, protected가 있는데요

이 접근제한자들은 변수, 함수, 클래스 선언 시 맨 앞에 붙여 사용하게 됩니다

ex) private var a = " "

public fun print {...}

internal class C {...}

 

상황에 따라 2가지 경우로 기능이 나뉘는데요

 

 

1. 패키지스코프에서는

  • public : 기본값이며 어떤 패키지에서도 접근 가능
  • internal : 같은 모듈 내에서만 접근 가능
  • private : 같은 파일 내에서만 접근 가능
  • protected : 패키지 스코프에서는 사용하지 않음

 

 

2. 클래스 스코프에서는

  • public : 기본값이며 클래스 외부에서 늘 접근 가능
  • private : 클래스 내부에서만 접근 가능
  • protected : 클래스 자신과 상속받은 클래스에서 접근 가능
  • internal : 클래스 스코프에서는 사용하지 않음

 

 

 

 

스코프멤버들의 가용 범위를 지정해둔 단위로 개발자는 의도에 따라 스코프 안에 변수나 함수, 클래스를 배치할 수 있으며

접근 제한자는 이러한 스코프의 외부와 내부에서 사용할 멤버를 분리하여 스코프 외부에서 건들이지 말아야 할 기능이나 값들을

안전하게 제한하는 용도를 가지고 있습니다

 

 

 

 

 

 

 

오늘의 포스팅은 여기서 마치도록 하겠습니다!

 

 

 

 

 

 

 

 

 

*위 글은 유튜브 테크과학! DeMo님의 강좌를 참고하여 작성하였습니다

 

'Kotlin' 카테고리의 다른 글

[Kotlin] 스코프 함수  (0) 2023.07.26
[Kotlin] 고차함수와 람다함수  (0) 2023.07.25
[Kotlin] 코틀린 프로젝트의 구조  (0) 2023.07.23
[Kotlin] 10. 오버라이딩과 추상화  (0) 2023.07.20
[Kotlin] 09. 클래스의 상속  (0) 2023.07.19