일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 플러터
- 크롤러
- textstyle
- DART
- Class
- Android
- 콜렉션
- python
- package
- Collection
- variable
- 코틀린
- kotlin
- text
- Yocto
- ML
- function
- List
- 클래스
- pushnamed
- 웹크롤러
- 함수
- 파이썬
- set
- import
- Flutter
- animation
- map
- crawler
- 다트
- Today
- Total
조용한 담장
코틀린(Kotlin) 클래스(Class) : 객체 표현식 과 선언 (Object Expressions and Declarations) 본문
코틀린(Kotlin) 클래스(Class) : 객체 표현식 과 선언 (Object Expressions and Declarations)
iosroid 2020. 1. 2. 16:05코틀린 클래스의 Object Expressions and Declarations 를 살펴보자
원문 https://kotlinlang.org/docs/reference/object-declarations.html 을 보며 정리.
새로운 클래스를 만들지 않고 특정 클래스에 약간의 수정만 한 오브젝트를 만드는 방법에 대해 살펴본다.
Object expressions
특정 type 을 상속한 익명(이름없는) 클래스(anonymous class) 의 오브젝트를 생성하는 방법
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { /*...*/ }
override fun mouseEntered(e: MouseEvent) { /*...*/ }
})
supertype 이 생성자를 가지고 있으면 파라미터를 전달해 줘야 한다.
: 뒤에 , 로 구분된 리스트 식으로 추가한다.
open class A(x: Int) {
public open val y: Int = x
}
interface B { /*...*/ }
val ab: A = object : A(1), B {
override val y = 15
}
만약 정말 단순한 오브젝트만 필요하다면 아래처럼 쓴다.
fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
익명(이름없는) 오브젝트 (anonymous object) 는 local 과 private 선언에서만 type 으로써 사용될 수 있다.
익명 오브젝트 (anonymous object) 를 public 함수의 리턴 타입으로 쓰거나 public property 의 타입으로 쓰면 둘의 실제 타입은 anonymous object 의 선언된 supertype 되거나, supertype 을 선언 안한 경우엔 Any 이 되게 된다.
anonymous object 에 추가된 멤버들은 접근이 불가능 해 진다.
class C {
// Private function, so the return type is the anonymous object type
private fun foo() = object {
val x: String = "x"
}
// Public function, so the return type is Any
fun publicFoo() = object {
val x: String = "x"
}
fun bar() {
val x1 = foo().x // Works
val x2 = publicFoo().x // ERROR: Unresolved reference 'x'
}
}
object expressions 안에 있는 코드는 외부 영역 (enclosing scope) 의 변수에 접근이 가능하다.
fun countClicks(window: JComponent) {
var clickCount = 0
var enterCount = 0
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
clickCount++
}
override fun mouseEntered(e: MouseEvent) {
enterCount++
}
})
// ...
}
Object declarations
kotlin 에서 싱글톤(singleton) 은 아래와 같이 선언할 수 있다.
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}
이는 object declaration 이라 하며 object 키워드를 사용한다.
object declaration 은 expression 이 아니므로 할당 구문 (assignment statement) 의 오른쪽에 쓰일 수 없다.
아래와 같이 사용한다.
DataProviderManager.registerDataProvider(...)
supertype 을 가질 수 있다.
object DefaultListener : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { ... }
override fun mouseEntered(e: MouseEvent) { ... }
}
object declaration 은 함수 안에 직접 중첩되어 선언되는 것 같이 로컬에 위치할 수 없지만, 다른 object declaration 이나 inner class 가 아닌 것에 중첩될 수는 있다.
Companion Objects
클래스 안에 위치하는 object declaration 은 companion 키워드가 적용될 수 있다.
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
companion object 의 멤버들은 클래스의 멤버처럼 호출할 수 있다.
val instance = MyClass.create()
companion object 의 이름 대신에 Companion 으로 사용될 수 있다.
class MyClass {
companion object { }
}
val x = MyClass.Companion
클래스의 이름이 companion object 의 레퍼런스 처럼 동작한다.
class MyClass1 {
companion object Named { }
}
val x = MyClass1
class MyClass2 {
companion object { }
}
val y = MyClass2
companion object 의 멤버들이 다른 언어의 static 멤버처럼 보이지만, 런타임시에 실제 오브젝트의 멤버들의 인스턴스 라는 점이 다르며, 인터페이스를 구현할 수 있다는 것이 다르다.
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
val f: Factory<MyClass> = MyClass
JVM 에서는 @JvmStatic 표시를 쓰면 실제 static method 와 field 로 생성된 companion object 의 멤버들을 쓸 수 있다.
Semantic difference between object expressions and declarations
object expressions 과 object declarations 의 중요한 semantic difference 가 있다.
- object expressions 는 사용되는 곳에서 바로 초기화 되고 실행된다.
- object declarations 는 처음 접근이 있을 때 늦은 초기화가 이루어 진다.
- companion object 는 해당 클래스가 로드되고, Java static initializer 의 semantics 와 매칭될 때 초기화 된다.
'kotlin' 카테고리의 다른 글
코틀린(Kotlin) : 함수(Function) (0) | 2020.01.02 |
---|---|
코틀린(Kotlin) 클래스(Class) : 위임(Delegation) (0) | 2020.01.02 |
코틀린(Kotlin) 클래스(Class) : 제네릭(Generics) (0) | 2020.01.02 |
코틀린(Kotlin) 클래스(Class) : 타입 별명 (Type aliases) (0) | 2019.12.31 |
코틀린(Kotlin) 클래스(Class) : 중첩 클래스 와 내부 클래스 (Nested and Inner Classes) (0) | 2019.12.31 |