Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Docker
  • rsocket
  • java
  • Wil
  • spring
  • Android
  • 코틀린 인 액션
  • 다이나믹 프로그래밍
  • 레포지토리
  • 문자열
  • MariaDB
  • kibana
  • 우아한테크코스
  • 백준
  • ec2
  • elasticsearch
  • grafana
  • 내림차순
  • 에라토스테네스의 체
  • 파이썬
  • 프로그래머스
  • enum
  • 프리코스
  • kotlin
  • til
  • 안드로이드
  • 코딩테스트
  • webflux
  • 코틀린
  • SQL

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Android/Kotlin

[Kotiln] Nested & inner class, Extension함수, Generics

2022. 9. 16. 20:57

Nested class / interface

1. 중첩된 클래스

class Outer {
    private val bar: Int = 1
    class Nested {
        fun foo() = 2
    }
}

val demo = Outer.Nested().foo() // == 2

Nested 클래스에서는 Outer 클래스의 프로퍼티나 함수에 접근 불가능

2. 중첩된 인터페이스

- 클래스 내부에 클래스나 인터페이스를 중첩하여 작성 가능

interface OuterInterface{
    class InnterClass
    interface InnerInterface
}

class OuterClass{
    class InnterClass
    interface InnterInterface
}

 

inner class

1. Outer 클래스의 멤버에 접근 가능

class Outer{
    private val bar: Int = 1
    inner class Innter {
        fun foo() = bar
    }
}

val demo = Outer.Nested().foo() // == 1

2. 무명 inner class

- 외부 클래스의 프로퍼티나 함수에 접근 가능

window.addMouseListener(object: MouseAdapter()
    override fun mouseClicked(e: MouseEvent){...}
    override fun mouseEntered(e: MouseEvnet){...}
})

 

this expressions

1. receiver 객체를 가리키는 식

    1) Implicit

    - 같은 클래스의 멤버를 호출할 때, this 생략 가능

class Store{
    private val products = listOf(
        Product("전자기기", "핸드폰")
    )
    fun showProducts(){
        products // 생략
        this.products
    }
}

    2) this@label

class Store{
    inner class Favorite {
        fun List<Product>.filterFaboriteItems(){
            this // == List<Product>
            this@filterFavoriteItems
            
            this@Favorite
            this@Store
        }
    }
}

 

Extension functions

- class를 상속받지 않아도 기능을 확장할 수 있음

// MutableList<Int> 타입의 함수에서 호출할 수 있는 함수를 추가
fun MutableList<Int>.swap(index1: Int, index2: Int){
    val tmp = this[index1] // this == MutableList<Int>
    this[index1] = this[index2]
    this[index2] = tmp
}

위 코드에서 MutableList<Int>는 Receiver type으로 확장할 클래스를 작성

val list = mutableListOf(1,2,3)
list.swap(0,2) // [3,2,1]

 

Extensions

1. 프로퍼티

- 프로퍼티 이름 앞에 Receiver type 선언

public val <T> List<T>.lastIndex: Int
    get() = this.size - 1

lastIndex 함수를 호출하는 리스트 원소의 모든 타입을 허용

val list = listOf(1,2,3,4,5)
println("${list.lastIndex}")

val strings = listOf("a", "b", "c", "d")
println("${strings.lastIndex}")

2. Companion object

class MyClass{
    companion object{}
}

fun MyClass.Companion.printCompanion(){
    println("companion")
}

// 메인에서 추가 함수 출력 가능
fun main(){
    MyClass.printCompanion()
}

3. 클래스 멤버

class Host(val hostname: String){
    fun printHostName(){print(hostname)}
}

class Connection(val host: Host, val prot: Int){
    fun printPort(){print(port)}
    
    // Connection 클래스에서 Host 클래스에 함수 추가
    fun Host.printConnectionString(){
        printHostname()
        print(":")
        printPort()
    }
    
    // Host 클래스의 멤버처럼 사용해 호출 가능
    fun connect(){
        host.printConnectionString()
    }
}

 Connection 클래스의 외부에서 확장함수 printConnectionString 함수 호출 불가능

4. Nullable receiver

- toString이 Nullable Any 클래스의 확장 함수이므로 어떠한 타입에도 toString 호출 가능

public fun Auy?.toString(): String
var nullableList: List<Int>? = null
println(nullableList.toString()) // null
nullableList = listOf(1,2,3,4,5)
println(nullableList.toString()) // [1,2,3,4,5]

 

Generics = Type parameter

- compile time에 type 안전성을 보장하면서, runtime에 다양한 타입으로 인스턴스화 할 수 있는 문법적 기능

fun <T> MutableList<T>.swap(index1: Int, index2: Int){
    val tmp = this[index1] // this == MutableList<Int>
    this[index1] = this[index2]
    this[index2] = tmp
}
val list = mutableListOf("a","b","c")
list.swap(0,2)

타입인자를 추론 -> String -> 컴파일 시  <T> 자리에 String 대입

 

fun <T:Number> MutableList<T>.swap(index1: Int, index2: Int){
    val tmp = this[index1] // this == MutableList<Int>
    this[index1] = this[index2]
    this[index2] = tmp
}

: Number을 추가하여 type parameter의 상한을 제한 할 수 있음

생략한 경우 : 기본값 Any?

val texts = mutableListOf("a","b","c")
val numbers = mutableListOf(1,2)
texts.swap(0,2) // Error
numbers.swap(0,2)

 

728x90

'Android > Kotlin' 카테고리의 다른 글

[Kotlin] enum, sealed class  (0) 2022.09.27
[Kotlin] 고차 함수, 람다, Scope functions  (0) 2022.09.18
[Kotlin] object  (0) 2022.09.16
[Kotlin] List, Set, Map, Collection Operations  (0) 2022.09.16
[Kotlin] Package, 가시성 변경자(public,private,internal,protected)  (0) 2022.09.11
    'Android/Kotlin' 카테고리의 다른 글
    • [Kotlin] enum, sealed class
    • [Kotlin] 고차 함수, 람다, Scope functions
    • [Kotlin] object
    • [Kotlin] List, Set, Map, Collection Operations
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바