For Programmer

12. 코틀린 - 변수와 접근제어자 본문

Programming language/Kotlin

12. 코틀린 - 변수와 접근제어자

유지광이 2021. 8. 25. 18:13

코틀린 내부에 변수는 간단히 전역변수와 지역변수가 있다. 

전역변수는 파일내부의 전역변수와 클래스 내부의 전역변수로 나눌 수 있다. 다음 코드를 보자

var number100:Int = 10 //파일내부의 전역변수

fun main(args:Array<String>){

}

class Reward(name:String){
    var name : String = name // 클래스 내부에서의 전역변수

    fun fun0(name:String){
        var fun0Name = name //fun0함수에서의 지역변수
   }
    fun fun1(string: String){
  
        name = string // 클래수 내부의 name전역변수에 접근가능하다.
        number100 = 10 //파일 내부의 전역 변수에 접근 가능하다.
        fun0Name = "good" //접근할 수 없다. fun0의 지역변수 이기 때문이다.
        
    }
}

이코드 안에 전역변수 지역변수의 개념이 다들어가 있다.

우선 number100 변수는 파일의 상단에 선언되어있다. 이는 즉, 파일내부의 전역변수이다. 따라서 파일내부에선 모든 클래스든,함수든 해당 변수에 접근이 가능하다.

 

그렇다면 Class내부에서 선언된 멤버변수는 무엇일까? 이는 클래스 내부에서만 사용할 수 있는 전역변수라고 생각하면된다. 즉 Class내부에서 함수를 만들었을때 해당 변수에 접근이 가능하다.위의 코드에서는 name 변수가 그 예이다.

 

마지막으로 fun0 과 fun1의 함수를 보자. 각각의 매개변수로 선언되어있는 name,string은 지역변수이기 때문에 해당 함수 내부에서만 사용할 수 있다. 또한 fun0 내부에서 선언된 fun0Name 변수는 fun0함수의 지역변수이기 때문에 fun1함수에서 접근할 수 없다. 또한 fun0 함수 밖의 Reward클래스 내에서도 접근할 수 없다는 점을 기억하자.

 

 접근제어자

코틀린에서 사용되는 접근제어자는 private, protected, internal, public 4가지 가 있다. (internal(같은 모듈 에서 접근가능 즉,안드로이드 컴파일 단위), protected(클래스 내부 밑 상속받은 클래스에서만 접근 가능 단,! 자바에서는 protected접근자가 같은 패키지 내부에서도 접근이 가능함, public(접근에 제한이 없음), private(클래스 내부에서만 접근 가능))) 그러나 자바와 다르게 코틀린에서는 변수와 함수의 접근제어자가 public이 기본값이다. 그래서 생략이 되면 모두 public으로 처리된다. 그렇다면 우리는 자주 사용되는 private의 사용법을 알아보자. 간단하게 private의 사용이유는 외부에서의 사용을 막기 위해서다. 다음의 코드를 보자. 

class Good{
    private var privateInt = 5
    var publicInt = 10
}

fun main(array: Array<String>){

    var good = Good() //Good 클래스 객체 생성
    println(good.publicInt) //10출력
    println(good.privateInt) //오류발생 접근불가
}

-> private으로 privateInt에 접근제어자를 설정해놓았으므로 접근이 불가하다. 

 

이러한 private 접근제어자는 클래스,함수,변수 에 적용이 가능한데 이를 사용하는 이유는 무엇일까? 다음코드를 보자.

package Kotlin

fun main(array: Array<String>){

    val night = Night(20,4)
    val monstert = Monstert(15,3)

    night.attack(monstert)
    monstert.attack(night)

    // night.hp = 10000 //에러 발생
    
}
class Night(private var hp:Int,private var power: Int){

    fun attack(monstert: Monstert){
        monstert.defense(power)
    }

    fun defense(damage: Int){
        hp -= damage
        if(hp>0) {
            heal()
            println("기사의 체력은 $hp 입니다.")
        }
        else println("기사가 죽었습니다.")
    }

    private fun heal(){ //외부애서 힐에 접근 불가
        hp += 3
    }
}

class Monstert(private var hp:Int,private var power: Int){

    fun attack(night: Night){
        night.defense(power)
    }

    fun defense(damage: Int){
        hp -= damage
        if(hp>0) println("몬스터의 체력은 $hp 입니다.")
        else println("몬스터가 죽었습니다.")
    }

    fun heal(){

    }
}

-> 코드를 간단히 설명하자면 기사와 몬스터 클래스 각각을 만들어 놓고 각각의 기사와 몬스터는 객체를 생성할 때 power와 hp를 변수로 받는다. 이렇게 hp와 power가 초기화가 되면 각각이 공격했을때(class 내부의 attack함수) 해당 power와 hp를 공격받은만큼 계산해서(defense함수) 남은 hp를 출력해준다. 여기서 만약에 hp,power,heal 과 같은 함수를 public으로 설정하고 우리가 private 접근제어자를 설정하지 않았다고 한다면 어떻게 될까?

우리는 객체를 생성 후 night.hp = 3000 혹은 night.heal() 로 hp를 수동조작할 수 있다. 아주 간단한 예이지만 이러한 것을 방지하기 위해 private를 사용한다고 생각하면 된다.

Comments