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 |