Android 앱/Kotlin Language

kotlin 코틀린 - package scope 접근제한자

arvigoes 2020. 3. 7. 23:07

package

패키지는 소스코드 파일 첫줄에 선언해 주시면 됩니다.

package com.tistory.arvigoes.testPackage

패키지의 이름은 마음대로 지으셔도 상관 없으나 만약 라이브러리화 해서 배포까지 염두에 둔다면

다른 모듈과의 충돌을 피하기위해 위와 같은 형태로 이름을 선언하시는게 유리 합니다.

많이들 사용하는 방식으로 회사(개인)의 메인 역순으로 순서대로 사용하고 마지막에 패키지의 용도 또는 식별가능한 의미있는 단어를 사용합니다.

만약 패키지 선언부가 없다면 kotilin은 이 파일을 default 패키지에 자동으로 포함됩니다.

이름충돌등이 발생할 수 있어 가능하면 패키지 이름을 지정하는 것이 좋습니다.

 

import

이미 만들어둔 패키지나, 외부모듈의 패키지를 가져와 포함 시키는 방법입니다.

package com.tistory.arvigoes.helloWorld

import com.tistory.arvigoes.testPackage.*		// 패키지 전체 사용가능
import com.tistory.arvigoes.testPackage.특정이름		// 패키지 내 특정클래스나 함수만 접근 가능
import com.tistory.arvigoes.testPackage.특정이름 as alias	// 패키지 내 특정클래스나 함수에 별칭으로 접근가능

패키지내의 모든것을 가져오면 편하긴 하나 덩치가 큰 패키지의 경우 또 다른 모듈과의 충돌등의 문제로

전체 (*) import 보다는 지정하여 import 하는 것이 좋습니다.

 

scope

package scope (같은 package 이름을 공유하는 범위)

 - 패키지 내에서 선언된 변수, 함수, 클래스

파일 scope

 - kotlin에서는 파일단위 제어는 package scope 로 포함됩니다

class scope

 - class 내에서 선언된 변수, 함수는 클래스

function scope

 - 함수내에 선언된 변수는 함수 내에서만 접근이 가능합니다.

 

다른 패키지의 맴버 변수, 함수, 클래스 등을 사용할때는 import 나 참조연산자(.) 으로 사용이 가능합니다.

이는 클래스에서 함수나 맴버 변수에 접근할때 사용한 참조연산자(.) 와 동일합니다.

package com.tistory.arvigoes.helloWorld

var newObject:com.tistory.arvigoes.TestClass = com.tistory.arvigoes.TestClass()
newObject.testFunc()

동일 scope 내에서는 맴버드을 모두 접근이 가능합니다.

함수내, 클래스내, 패키지는 패키지 명이 동일하더라도 파일단위로 scope 가 나뉩니다.

패키지(파일)내에서 선언된 변수, 함수, 클래스는 동일 파일내에서는 모두 접근이 가능합니다.

그리고 클래스내에 모든변수, 함수등은 클래스 내의 모든 함수에서 접근 가능합니다.

함수내에서는 함수내에선언된 모든 것들은 함수내에서만 접근이 가능합니다.

Scope 외부에서 내부의 접근에는 위에서 설명했듯이 참조연산자를 사용 하여 접근이 가능 합니다.

package com.tistory.arvigoes.helloWorld

var newObject:com.tistory.arvigoes.TestClass = com.tistory.arvigoes.TestClass()	// 다른 패키지 참조
newObject.testFunc()		// 클래스내 멤버 참조

이렇게 접근하는것을 패키지 또는 클래스에 대해서는 라이브러리 개발자가 제한을 할 수 있습니다.

다음 예를 한번 보도록 할까요?

class Dog {
    var nativeSound = "mung"
    var legCount = 4
    fun sound() {
        println(nativeSound)
    }
    fun run() {
        println("${legCount} leg")
    }
}
fun main(){
    var mung = Dog()

    mung.nativeSound = "mew"
    mung.legCount = 2
    
    mung.sound()
    mung.run()
}

실행을 해 보도록 하겠습니다.

갑자기 개가 고양이 소리를 내고 다리가 2개가 됩니다.

이렇게 Dog 라는 클래스를 사용자가 마음대로 수정하지 못 하도록 라이브러리 개발자는 책임을 져야 합니다.

접근제한자를 통해 이러한 접근을 막을 수 있습니다.

var 대신 val 선언으로도 막을 수 있지만 지금은 접근제한자를 통해 막아 보도록 하겠습니다.

 

우선 접근 제한자의 종류에 대해 알아 보도록 하겠습니다.

제한자 클래스 패키지
public 클래스 외부에서 접근 가능 (default) 어떤 패키지에서도 접근 가능 (default)
protected 클래스 자신과 상복받은 클래스에서 접근 가능 사용안함
private 클래스 내부에서만 접근 가능 같은 파일 내에서만 접근 가능
internal 사용안함 같은 모듈내에서만 접근 가능

변수, 함수, 클래스에 사용가능한 접근 제한자 입니다.

아무것도 선언하지 않으면 default 로 public 이 되어 언제 어디서든 접근이 가능 합니다.

 

접근제한자의 종류에 대해서 알아봤으니 한번 적용 해 보도록 하겠습니다.

class Dog {
    private var nativeSound = "mung"
    private var legCount = 4
    fun sound() {
        println(nativeSound)
    }
    fun run() {
        println("${legCount} leg")
    }
    protected fun changeSound(native:String) {
    	nativeSound = native
    }
}
fun main(){
    var mung = Dog()

    // mung.nativeSound = "mew"			// error
    // mung.legCount = 2			// error
    
    mung.sound()
    mung.run()
}

사용 방법은 간단 합니다.

선언에 앞서 먼저 접근제한자 키워드를 쓰시면 됩니다.

변수는 private 로 선언함으로써 상속받는 클래스에서도 직접적으로 nativeSound 값변경은 불가능 합니다.

그러나 chageSound 라는 함수를 protected 로 선언해서 상속받는 클래스에서 간접적으로 변경은 가능합니다.

"왈왈" 짖는 개도 있으니까 변경은 가능하도록 허용 해 줍니다.

그러나 외부에서는 변경이 불가능 합니다.

 

package 에서도 사용방법은 동일 합니다.

package com.tistory.arvigoes.DogWorld
public class Dog {
    private var nativeSound = "mung"
    private var legCount = 4
    fun sound() {
        println(nativeSound)
    }
    fun run() {
        println("${legCount} leg")
    }
    protected fun changeSound(native:String) {
    	nativeSound = native
    }
}

접근제한자 키워드를 먼저 쓰고 클래스, 함수, 변수 를 선언 하시면 됩니다.