타닥타닥 개발자의 일상

Kotilin 지역변수 / 글로벌 변수 / 함수의 파라미터로 함수 삽입 / getter, setter / 오버로드 / 접근지정자(protected, internal) / by lazy 본문

코딩 기록/Kotlin

Kotilin 지역변수 / 글로벌 변수 / 함수의 파라미터로 함수 삽입 / getter, setter / 오버로드 / 접근지정자(protected, internal) / by lazy

NomadHaven 2022. 1. 25. 22:50

 지역변수 / 글로벌 변수 / 파라미터로 함수 삽입 예시

var global = 10 //전역에서 접근할수 있는 글로벌 변수

fun main(args: Array<String>) {

    val res1 = funcParam(3,4, ::sum) //파라미터에 sum함수 삽입
    println(res1) //sum(a:Int, b:Int) =a+b 이므로 res1출력값 7

    hello(::text) //Hi! Hello World 출력
    hello { a, b -> text(a, b) }//Hi! Hello World 출력
    hello({a, b -> text(a, b)}) //Hi! Hello World 출력


    //일반 변수처럼 할당할 수 있다.
    val likeLamda = ::sum //sum 함수 대신 likeLamda로 접근

    println(likeLamda(6,7)) //13

    global =11 //글로벌 변수라서 메인 함수 안에서 접근 가능

    fun localFunc(){

        global=12 // 글로벌 변수라서 로컬 함수 안에서 접근 가능

        var temp:Int //지역변수 temp
    }

   // temp=12 지역변수. global과 달리 밖에서 접근하면 에러 뜬다

    localFunc()

    println("global : $global") // 마지막 접근값인 12로 출력 (출력값: global : 12 )
}

fun sum(a:Int, b:Int) =a+b

fun text(a:String, b:String)="Hi! $a $b"

fun funcParam(a: Int, b: Int, c: (Int, Int)->Int):Int{
    return c(a,b)
}

fun hello(body:(String, String) ->String){ //body는 단순 변수명
    println(body("Hello","World"))
}

위 코드의 출력값


 

Java의 getter , setter 사용을 Kotlin에서 한다면

fun main(args: Array<String>) {
    var cls = Person("길동","홍",24) //Person 클래스의 생성자  cls
    cls.firstName = "수길" //이름 길동에서 수길로 변경
    println(cls.getFullName()) //클래스 내 getFullName함수 이용. (출력값:수길 홍 24) 

    val user = Human("abc123","1004","성춘향") //Human클래스의 생성자  user, 파라미터 입력하면서 데이터입력.
    println("${user.id}") //출력값:abc123
    println("${user.name}") //출력값:성춘향
    user.password="1234" // password "1234"로 설정

    val bird = Bird() //Bird클래스의 생성자 bird
    bird.color="red" // color속성 red로 초기화
    println("${bird.color}") //출력값: red

    bird.fly() //출력값: (fly wing:2) 새 생성자에서 초기화 하지 않았으므로 디폴트값 2로 출력
    bird.sing("long") //출력값:(sing vol:long)

}

class Person{
    var firstName:String
    var lastName: String
    var age:Int



    constructor(firstName: String, lastName:String, age:Int){
        this.firstName = firstName
        this.lastName =lastName
        this.age =age
    }

    fun getFullName():String{
        return "$firstName $lastName $age"
    }
}

//Dto, VO
data class Human(val id:String, var password:String, val name:String) //data붙여서 DTO클래스로 사용
{
    fun getFullName(): String {
        return "$id $password $name"

    }
}

class Bird{
    //property(속성)
    var name:String = "mybird"
    var wing:Int = 2
    var vol:String = "short"
    var color:String = "blue"

    fun fly() = println("fly wing: $wing")
    fun sing(vol:String)=println("sing vol: $vol") //vol이라는 String 형 변수를 파라미터로 받는 함수

}

위 코드의 출력값

 

 

 

fun main(args: Array<String>) {

    val user = User(1,"Tom",18)
    val id = user.id //var id = 1
    println(id) // 출력값: 1

    user.name = "정수동" //출력값: name setter 정수동
    user.name = "ariana grande" //출력값: name setter ARIANA GRANDE

    val kim = FakeAge()
    kim.age = 15
    println(kim.toString()) //출력값: FakeAge(age=18)

    val lee = FakeAge()
    lee.age = 36
    println(lee.toString()) // 출력값: FakeAge(age=33)

    
}

class FakeAge{
    var age:Int = 0 // var age 0으로 초기화
        set(value){ //value 값을 입력받는다고 할때
            field = when{
                value <18 -> 18  // 입력된 값이 18세 미만이면 18
                value in 18..30 -> value //입력된 값이 18이상 30 이하면 value값 그대로
                else -> value -3 //30 초과면 -3한 값으로
            }
        }

    override fun toString(): String {
        return "FakeAge(age=$age)" //toString 함수 호출시에는 위에서 초기화된 age 출력
    }

}


// setter, getter
class  User(_id:Int, _name:String, _age:Int){
    var id:Int= _id //_id값 var id로 초기화
        get() = field  //filed 값을 가져온다. getter

    var name: String = _name //_name을 var name으로 초기화
        get()= field //getter
        
        //value는 임의의 변수. 의미가 있는 단어 아니다.
        set(value){ //입력받은 value값으로 지정
            println("name setter")
            field = value.toUpperCase() //filed값을 대문자로 변환
            println(field)
        }

    var age: Int = _age // _age를 var age로 초기화
    get(){
      return field
    }
    set(v){ //입력받은 v 값으로 지정
        field = v 
    }

}

위 코드의 출력값


Kotlin의 접근 지정자 protect, internal / 오버로드

fun main(args: Array<String>) {

    val human = Human() //Person 클래스를 상속받은 Hunman 클래스의 생성자 human
    human.method()
   // human.protectVar=25 접근 지정자가 protected라서 접근이 안된다.
    human.interVar=22 //접근지정자가 internal이면 같은 패키지 내에서 접근 허용해준다.

    val bird = Bird("나이팅게일",2,"blue")
    println(bird.toString()) 
    //출력값 : Bird(name='나이팅게일', wing=2, color='blue')


    val mycls = MyClass() //출력값: 123

    val base = Bass("abc","123") //parameter가 일치하는 생성자에 오버라이딩 됨
    println(base.toString())
   // 출력값:constructor(abc:String, 123:String, 22:Int)
   //        Base(id='abc',pwd='123',age=22)

    val base2 = Bass("abc","234") //parameter가 일치하는 생성자에 오버라이딩 됨
    println(base2.toString())
   // 출력값: constructor(abc:String, 234:String, 22:Int)
   //         Base(id='abc',pwd='234',age=22) 

    val base3 = Bass("cde")
    println(base3.toString())
    //출력값: constructor(cde:String, 1004:String, 24:Int)
    //        Base(id='cde',pwd='1004',age=24)

}

class Bass(val id:String, val pwd:String, val age:Int){ // -> 기본 생성자

    constructor(id:String, pwd:String) : this(id,pwd, 22) { // -> 보조 생성자(오버로드함)
        println("constructor($id:String, $pwd:String, $age:Int)")
    }

    constructor(id:String) : this(id, "1004", 24){ // -> 보조 생성자(오버로드함)
        println("constructor($id:String, $pwd:String, $age:Int)")
        }

    override fun toString(): String {
        return "Base(id='$id',pwd='$pwd',age=$age)"
    }

}


class MyClass{
    var number : Int

    init { //내부 초기화
        number = 123
        println(number)
    }
}


//property 선언 + constructor
class Bird(var name: String,var wing: Int,val color: String){ //외부 초기화

    fun fly() = println("Fly Wing : $wing")

    override fun toString(): String {
        return "Bird(name='$name', wing=$wing, color='$color')"
    }

}



//접근 지정자
open class Person{ //상속할 부모 클래스에는 open을 붙여준다.
    val firstName: String = "" //firstName변수 초기화
    val lastName: String = "" //lastName변수 초기화
    private var age: Int = 24 //age의 디폴트값 24

    protected var protectVar: Int = 12 //접근 지정자가 protected인 변수 protectVar
    internal var interVar:Int = 20 //접근 지정자가 internal인 변수 interVar


    private fun privateFunc(){ //접근 지정자가 prviate인 함수 privateFunc
    }

    override fun toString(): String {

        privateFunc() // 클래스 내부에선 private 함수 접근 가능
        return "Person(firstName='$firstName', lastName='$lastName', age=$age)"
    }
}

class Human : Person(){ // Person클래스를 상속받은 Human 클래스

    fun method(){
        protectVar = 23 // 상속을 받았으므로 접근 지정자가 protected 인 변수여도 접근해서 초기화 가능.
        println(protectVar) 

        interVar =21 //상속을 받았으므로접근 지정자가 internal인 변수에 접근 가능.
        println(interVar)

    }
}

위 코드의 출력값


 

by lazy라는 제어문과 함수와 변수가 호출되는 순서

fun main(args: Array<String>) {

    val lazyTest = LazyTest() // 1. 제일 처음 시작되는 곳
    lazyTest.flow() //3. 세번째 시작되는 곳

}

    class LazyTest{

        init{
            println("init block") //2. 두번째로 시작
        }
        val subject by lazy{ // by lazy는 변수가 호출되기 전까진 초기화를 안한다
            println("lazy initialized") //6. 여섯번째
            "subject value" //7. 일곱번째
        }

        fun flow(){
            println("subject not initialized") //4. 네번째
            println("subject : $subject") // 5. 다섯번째 -> 최초 초기화 이루어진다. 실제 val subject가 호출되는 시점

        }

    }



/*
 lazy : 느긋한 계산법
 필요한 때까지 계산을 늦추는 기법이다.
 */

Comments