본문 바로가기

기타/안드로이드

21. Kotlin의 generic, enum, data class, object, 범위함수

Kotlin의 generic, enum, data class, object, companion object, 범위함수

제네릭, 객체, 확장

 

제네릭, 객체, 확장  |  Android Developers

요약 추가

developer.android.com

위의 페이지를 참고하여 kotlin의 추가적인 문법적인 요소들을 알아보자

 

개요

오늘은 kotlin의 문법에 대해서 더 알아가는 시간을 가져보자

 

1. generic

generic은 자바나 C++ 등을 해봤다면 익숙한 친구일텐데,

구체적이지 않고 일반적인 자료형이라고 생각하면 좋을 것 같다

 

자료형을 구체적으로 명시하지 않고 어떤 자료형이던지 들어갈 수 있게  해주는 친구다

다음과 같이 클래스, 함수, 메소드에 쓸 수 있다

fun main() {
    val a = JustClass<String>("hello")
    a.printClass()
    val b = JustClass<Int>(123)
    b.printClass()

    println(addFun(1.3, 2.3))
}

class JustClass<K>(val justProperty: T){
    fun printClass(){
        print("just property : ")
        println(justProperty)
    }
}

fun <T: Double> addFun(num1: T, num2: T): Double {
    return (num1 + num2)
}

위의 코드에서 클래스의 경우는 그냥 K라고 써놨지만

함수의 경우는 T에 Double만 들어갈 수 있게 제약을 걸어놨다

 

 

2. enum

enum은 상수를 모아서 이름을 붙였다고 생각하면 된다

enum class Week {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
    FRIDAY, SATURDAY, SUNDAY
}
fun main() {
    val d = Day(Week.MONDAY, 1, 3, 2003)
    d.printClass()
}

class Day(
    val dayOfWeek: Week, val day: Int,
    val month: Int, val year: Int
) {
    fun printClass(){
        println("day of week : " + dayOfWeek)
        println("day : " + day)
        println("month : " + month)
        println("year : " + year)
    }
}

여타 다른 언어에서도 볼 수 있기 때문에 자세한 설명은 넘어가자

 

 

3. data class

얘는 뭐 이름 그대로 그냥 data를 담는 클래스이다

그래서 메소드는 없다

fun main() {
    val a = BodyInfo(173, 69)
    println(a.toString())
    val b = CarInfo(30000000)
    println(b.toString())
}

결과

BodyInfo(height=173, weight=69)
CarInfo@439f5b3d

이와 같은 toString 등의 메소드에 특별한 기능이 생긴다

예전에 KeyboardOptions를 다룰 때 봤던 copy함수가 그 예시이다

 

4. object

싱글톤 객체라는 말을 아는가?

인스턴스가 유일한 한 개 뿐인 클래스를 말한다

두 개이면 이상한 객체들이 있다(플레이어의 점수를 추적하며 기록하는 객체 등)

그런 친구들을 구현하기 위한 키워드엔 object가 있다

 

다 똑같은데 그냥 키워드만 object로 바뀌었다고 생각하면 된다

fun main() {
    JustObject.justMethod()
}

object JustObject{
    val justProperty = 3
    fun justMethod(){
        println(justProperty)
    }
}

이미 인스턴스화 되어있다고 생각하고 접근하면 된다

 

 

5. companion object

이 친구는 자바의 static과 같은 친구이다

자바의 static 변수는 모든 객체가 공유하는 변수로 클래스 변수라고도 부른다

코틀린에는 static 키워드가 없고 companion object를 활용한다

companion이 동반자라는 의미이기 때문에 얼추 이해가 되는 이름이라고 할 수 있겠다

fun main() {
    val jc1 = JustClass()
    val jc2 = JustClass()

    jc1.printValue()
    jc2.changeValue(3)
    jc1.printValue()
}

class JustClass() {
    companion object {
        var justProperty = 1
    }

    fun changeValue(value: Int) {
        justProperty = value
    }

    fun printValue() {
        println(justProperty)
    }
}

<실행결과>

1
3

 

 

 

6. 확장 속성 및 메소드

클래스 정의 이후에 속성과 메소드를 추가할 수 있다

fun main() {
    val JC = JustClass()
    JC.justMethod()
    JC.justMethod2()
}

class JustClass(val justProperty: String = "Kim"){
    fun justMethod(){
        println("hello ${justProperty}")
    }
}

val JustClass.justProperty2: String
    get() = "Lee"
fun JustClass.justMethod2() {
    println("bye ${justProperty2}")
}

이때 확장속성은 get-only이다

 

 

7. 범위함수

없어도 되는데 있으면 편한 기능을 제공해주는 친구들이다

호출한 객체를 자신의 인자로 이용하는 것이 특징이다

대표적으로 let, apply가 있다

fun main() {
    val jc = JustClass().apply(){
        justProperty = "Park"
        justProperty = "Choi"
    }
    jc.justMethod()

    val jc2 = JustClass()
    jc2.let(){
        it.justProperty = "Park"
        it.justProperty = "Choi"
        it.justMethod()
    }
}

apply는 내부 속성을 변경한 뒤 변경된 객체를 반환해준다

속성을 변경할 때 속성 앞에 객체 이름을 쓰지 않아도 되서 가독성이 좋아진다

 

let은 클래스 멤버에 it을 통해서 접근할 수 있게 해준다

역시 가독성이 좋아진다