Kotlin 학습노트15--의뢰
31460 단어 Kotlin
Kotlin 학습노트15--의뢰
전언
전편에서는 Kotlin의 Object 키워드를 배웠고, 오늘은 Kotlin의 의뢰를 계속 배워보겠습니다.
kotlin 위임
위탁 모델은 소프트웨어 디자인 모델 중의 기본적인 기교이다.위탁 모드에서 두 대상이 같은 요청을 처리하는 데 참여하고 요청을 받은 대상은 요청을 다른 대상에게 위탁하여 처리한다.
Kotlin은 위탁 모드를 직접 지원하여 더욱 우아하고 간결하게 합니다.Kotlin은 키워드 by를 사용하여 위임을 수행합니다.
클래스 위임
클래스의 의뢰는 하나의 클래스에서 정의된 방법으로 실제적으로 다른 클래스의 대상을 호출하는 방법으로 이루어진다.
다음 예에서 파생 클래스 Derived는 인터페이스 Base의 모든 방법을 계승하고, 이 방법을 실행하기 위해 전송된 Base 클래스의 대상을 의뢰합니다.//
interface Base {
fun print()
}
//
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
// by
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 10
}
Derived 성명에서 by 자구는 b를 Derived의 대상 실례 내부에 저장하고 컴파일러는 Base 인터페이스에서 계승하는 모든 방법을 생성하여 b에 호출을 전달합니다.
위탁으로 이루어진 인터페이스 구성원 덮어쓰기
컴파일러는 위탁 대상이 아닌 오버라이드 덮어쓰기를 사용합니다.interface Base {
fun printMessage()
fun printMessageLine()
}
class BaseImpl(val x: Int) : Base {
override fun printMessage() { println("BaseImpl printMessage $x") }
override fun printMessageLine() { println("BaseImpl printMessageLine $x") }
}
class Derived(b: Base) : Base by b {
override fun printMessage() { println("override printMessage abc") }
}
fun main() {
val b = BaseImpl(10)
Derived(b).printMessage()
Derived(b).printMessageLine()
}
인쇄 결과:override printMessage abc
BaseImpl printMessageLine 10
그러나 이런 방식으로 다시 쓴 구성원은 위탁 대상의 구성원에서 호출되지 않으며 위탁 대상의 구성원은 자신의 인터페이스 구성원에 대한 접근만 할 수 있음을 주의하십시오.interface Base {
val message: String
fun print()
}
class BaseImpl(val x: Int) : Base {
override val message = "BaseImpl: x = $x"
override fun print() { println(message) }
}
class Derived(b: Base) : Base by b {
// b `print`
override val message = "Message of Derived"
}
fun main() {
val b = BaseImpl(10)
val derived = Derived(b)
// ,
derived.print()
println(derived.message)
}
인쇄 결과:BaseImpl: x = 10
Message of Derived
속성 위임
속성 의뢰란 하나의 클래스의 특정한 속성 값을 클래스에서 직접 정의하는 것이 아니라 이를 하나의 에이전트 클래스에 의뢰하여 해당 클래스의 속성에 대한 통일된 관리를 실현하는 것을 말한다.
등록 정보 위임 구문 형식:val/var < >: < > by < >
위탁 모델은 소프트웨어 디자인 모델 중의 기본적인 기교이다.위탁 모드에서 두 대상이 같은 요청을 처리하는 데 참여하고 요청을 받은 대상은 요청을 다른 대상에게 위탁하여 처리한다.
Kotlin은 위탁 모드를 직접 지원하여 더욱 우아하고 간결하게 합니다.Kotlin은 키워드 by를 사용하여 위임을 수행합니다.
클래스 위임
클래스의 의뢰는 하나의 클래스에서 정의된 방법으로 실제적으로 다른 클래스의 대상을 호출하는 방법으로 이루어진다.
다음 예에서 파생 클래스 Derived는 인터페이스 Base의 모든 방법을 계승하고, 이 방법을 실행하기 위해 전송된 Base 클래스의 대상을 의뢰합니다.//
interface Base {
fun print()
}
//
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
// by
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 10
}
Derived 성명에서 by 자구는 b를 Derived의 대상 실례 내부에 저장하고 컴파일러는 Base 인터페이스에서 계승하는 모든 방법을 생성하여 b에 호출을 전달합니다.
위탁으로 이루어진 인터페이스 구성원 덮어쓰기
컴파일러는 위탁 대상이 아닌 오버라이드 덮어쓰기를 사용합니다.interface Base {
fun printMessage()
fun printMessageLine()
}
class BaseImpl(val x: Int) : Base {
override fun printMessage() { println("BaseImpl printMessage $x") }
override fun printMessageLine() { println("BaseImpl printMessageLine $x") }
}
class Derived(b: Base) : Base by b {
override fun printMessage() { println("override printMessage abc") }
}
fun main() {
val b = BaseImpl(10)
Derived(b).printMessage()
Derived(b).printMessageLine()
}
인쇄 결과:override printMessage abc
BaseImpl printMessageLine 10
그러나 이런 방식으로 다시 쓴 구성원은 위탁 대상의 구성원에서 호출되지 않으며 위탁 대상의 구성원은 자신의 인터페이스 구성원에 대한 접근만 할 수 있음을 주의하십시오.interface Base {
val message: String
fun print()
}
class BaseImpl(val x: Int) : Base {
override val message = "BaseImpl: x = $x"
override fun print() { println(message) }
}
class Derived(b: Base) : Base by b {
// b `print`
override val message = "Message of Derived"
}
fun main() {
val b = BaseImpl(10)
val derived = Derived(b)
// ,
derived.print()
println(derived.message)
}
인쇄 결과:BaseImpl: x = 10
Message of Derived
속성 위임
속성 의뢰란 하나의 클래스의 특정한 속성 값을 클래스에서 직접 정의하는 것이 아니라 이를 하나의 에이전트 클래스에 의뢰하여 해당 클래스의 속성에 대한 통일된 관리를 실현하는 것을 말한다.
등록 정보 위임 구문 형식:val/var < >: < > by < >
//
interface Base {
fun print()
}
//
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
// by
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 10
}
interface Base {
fun printMessage()
fun printMessageLine()
}
class BaseImpl(val x: Int) : Base {
override fun printMessage() { println("BaseImpl printMessage $x") }
override fun printMessageLine() { println("BaseImpl printMessageLine $x") }
}
class Derived(b: Base) : Base by b {
override fun printMessage() { println("override printMessage abc") }
}
fun main() {
val b = BaseImpl(10)
Derived(b).printMessage()
Derived(b).printMessageLine()
}
override printMessage abc
BaseImpl printMessageLine 10
interface Base {
val message: String
fun print()
}
class BaseImpl(val x: Int) : Base {
override val message = "BaseImpl: x = $x"
override fun print() { println(message) }
}
class Derived(b: Base) : Base by b {
// b `print`
override val message = "Message of Derived"
}
fun main() {
val b = BaseImpl(10)
val derived = Derived(b)
// ,
derived.print()
println(derived.message)
}
BaseImpl: x = 10
Message of Derived
속성 의뢰란 하나의 클래스의 특정한 속성 값을 클래스에서 직접 정의하는 것이 아니라 이를 하나의 에이전트 클래스에 의뢰하여 해당 클래스의 속성에 대한 통일된 관리를 실현하는 것을 말한다.
등록 정보 위임 구문 형식:
val/var < >: < > by < >
위탁된 클래스를 정의합니다. 이 클래스는 getValue () 방법과 setValue () 방법을 포함하고, 매개 변수thisRef는 위탁된 클래스의 대상이며, prop는 위탁된 속성의 대상입니다.
import kotlin.reflect.KProperty
//
class Example {
var p: String by Delegate()
}
//
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, ${property.name} "
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef ${property.name} $value")
}
}
fun main(args: Array<String>) {
val e = Example()
println(e.p) // , getValue()
e.p = "Runoob" // setValue()
println(e.p)
}
결과 출력:
Example@433c675d, p
Example@433c675d p Runoob
Example@433c675d, p
표준 위탁
Kotlin의 표준 라이브러리에는 속성을 실현하기 위한 공장 방법이 많이 내장되어 있습니다.lazy () 는 함수입니다. Lambda 표현식을 매개 변수로 받아들여 Lazy 실례의 함수를 되돌려줍니다. 되돌아오는 실례는 지연 속성을 실현하는 의뢰로 사용할 수 있습니다. 첫 번째 get () 호출은 lazy () 에 전달된 lamda 표현식을 실행하고 결과를 기록합니다. 다음 get () 호출은 기록된 결과만 되돌려줍니다.val lazyValue: String by lazy {
println("computed!") // ,
"Hello"
}
fun main(args: Array<String>) {
println(lazyValue) // ,
println(lazyValue) // ,
}
결과 출력:computed!
Hello
Hello
관찰가능 속성 Observable
observable는 관찰자 모드를 실현하는 데 사용할 수 있습니다.Delegates.observable () 함수는 두 개의 인자를 받아들인다. 첫 번째는 초기화 값이고, 두 번째는 속성 값 변화 이벤트의 응답기 (handler) 이다.속성에 값을 부여한 후에 이벤트를 실행하는 응답기(handler)는 세 가지 인자가 있습니다. 그것이 바로 값을 부여받은 속성, 옛 값과 새 값입니다.import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable(" ") {
prop, old, new ->
println(" :$old -> :$new")
}
}
fun main(args: Array<String>) {
val user = User()
user.name = " "
user.name = " "
}
결과 출력: : -> :
: -> :
맵에 속성 저장
흔히 볼 수 있는 용례는 맵에 속성을 저장하는 값이다.이것은 JSON을 해석하거나 다른'동적'일을 하는 응용 프로그램에 자주 나타난다.이런 상황에서 당신은 실례 자체를 비추어 의뢰로 의뢰 속성을 실현할 수 있습니다.class Site(val map: Map<String, Any?>) {
val fristName: String by map
val lastName: String by map
}
fun main(args: Array<String>) {
//
val p = Site(mapOf(
"fristName" to "Jim",
"lastName" to "Green"
))
//
println(p.fristName)
println(p.lastName)
}
결과 출력:Jim
Green
Not Null
notNull은 초기화 단계에서 속성 값을 정할 수 없는 경우에 적용됩니다.속성이 값을 부여하기 전에 접근되면 이상이 발생합니다.class Foo {
var notNullBar: String by Delegates.notNull<String>()
}
foo.notNullBar = "bar"
println(foo.notNullBar)
속성 위임 요구 사항
읽기 전용 속성 (즉 val 속성) 에 대한 의뢰는 getValue () 라는 함수를 제공해야 합니다.이 함수는 다음 매개변수를 적용합니다.
val lazyValue: String by lazy {
println("computed!") // ,
"Hello"
}
fun main(args: Array<String>) {
println(lazyValue) // ,
println(lazyValue) // ,
}
computed!
Hello
Hello
observable는 관찰자 모드를 실현하는 데 사용할 수 있습니다.Delegates.observable () 함수는 두 개의 인자를 받아들인다. 첫 번째는 초기화 값이고, 두 번째는 속성 값 변화 이벤트의 응답기 (handler) 이다.속성에 값을 부여한 후에 이벤트를 실행하는 응답기(handler)는 세 가지 인자가 있습니다. 그것이 바로 값을 부여받은 속성, 옛 값과 새 값입니다.
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable(" ") {
prop, old, new ->
println(" :$old -> :$new")
}
}
fun main(args: Array<String>) {
val user = User()
user.name = " "
user.name = " "
}
결과 출력:
: -> :
: -> :
맵에 속성 저장
흔히 볼 수 있는 용례는 맵에 속성을 저장하는 값이다.이것은 JSON을 해석하거나 다른'동적'일을 하는 응용 프로그램에 자주 나타난다.이런 상황에서 당신은 실례 자체를 비추어 의뢰로 의뢰 속성을 실현할 수 있습니다.class Site(val map: Map<String, Any?>) {
val fristName: String by map
val lastName: String by map
}
fun main(args: Array<String>) {
//
val p = Site(mapOf(
"fristName" to "Jim",
"lastName" to "Green"
))
//
println(p.fristName)
println(p.lastName)
}
결과 출력:Jim
Green
Not Null
notNull은 초기화 단계에서 속성 값을 정할 수 없는 경우에 적용됩니다.속성이 값을 부여하기 전에 접근되면 이상이 발생합니다.class Foo {
var notNullBar: String by Delegates.notNull<String>()
}
foo.notNullBar = "bar"
println(foo.notNullBar)
속성 위임 요구 사항
읽기 전용 속성 (즉 val 속성) 에 대한 의뢰는 getValue () 라는 함수를 제공해야 합니다.이 함수는 다음 매개변수를 적용합니다.
class Site(val map: Map<String, Any?>) {
val fristName: String by map
val lastName: String by map
}
fun main(args: Array<String>) {
//
val p = Site(mapOf(
"fristName" to "Jim",
"lastName" to "Green"
))
//
println(p.fristName)
println(p.lastName)
}
Jim
Green
notNull은 초기화 단계에서 속성 값을 정할 수 없는 경우에 적용됩니다.속성이 값을 부여하기 전에 접근되면 이상이 발생합니다.
class Foo {
var notNullBar: String by Delegates.notNull<String>()
}
foo.notNullBar = "bar"
println(foo.notNullBar)
속성 위임 요구 사항
읽기 전용 속성 (즉 val 속성) 에 대한 의뢰는 getValue () 라는 함수를 제공해야 합니다.이 함수는 다음 매개변수를 적용합니다.
번역 규칙
Kotlin 컴파일러는 모든 위임 속성의 실현 뒤에 보조 속성을 생성하여 위임합니다.예를 들어 속성 prop에 대해 숨겨진 속성 prop$delegate를 생성하고, 액세서리의 코드는 이 추가 속성에 간단하게 의뢰합니다.class C {
var prop: Type by MyDelegate()
}
// :
class C {
private val prop$delegate = MyDelegate()
var prop: Type
get() = prop$delegate.getValue(this, this::prop)
set(value: Type) = prop$delegate.setValue(this, this::prop, value)
}
Kotlin 컴파일러는 매개 변수에서prop에 대한 모든 필요한 정보를 제공합니다. 첫 번째 매개 변수인this는 외부 클래스 C의 실례를 인용하고this: property는 Kproperty 형식의 반사 대상입니다. 이 대상은prop 자체를 설명합니다.
위탁을 제공하다
provideDelegate 조작부호를 정의함으로써 위탁 대상의 논리를 실현하는 속성을 확장할 수 있습니다.만약by 오른쪽에 있는 대상이provideDelegate를 구성원이나 확장 함수로 정의한다면, 이 함수를 호출하여 속성 의뢰 실례를 만들 것입니다.
provideDelegate의 가능한 사용 장면은 속성을 만들 때 (Getter나setter뿐만 아니라) 속성 일치성을 검사하는 것입니다.provideDelegate의 매개변수는 getValue와 같습니다.
class C {
var prop: Type by MyDelegate()
}
// :
class C {
private val prop$delegate = MyDelegate()
var prop: Type
get() = prop$delegate.getValue(this, this::prop)
set(value: Type) = prop$delegate.setValue(this, this::prop, value)
}
provideDelegate 조작부호를 정의함으로써 위탁 대상의 논리를 실현하는 속성을 확장할 수 있습니다.만약by 오른쪽에 있는 대상이provideDelegate를 구성원이나 확장 함수로 정의한다면, 이 함수를 호출하여 속성 의뢰 실례를 만들 것입니다.
provideDelegate의 가능한 사용 장면은 속성을 만들 때 (Getter나setter뿐만 아니라) 속성 일치성을 검사하는 것입니다.provideDelegate의 매개변수는 getValue와 같습니다.
예:
class MyProvider {
operator fun provideDelegate(thisRef: MyTestClass, prop: KProperty<*>): ReadOnlyProperty<MyTestClass, String> {
println("do something") // getValue
return object: ReadOnlyProperty<MyTestClass, String> { // getValue
override fun getValue(thisRef: MyTestClass, property: KProperty<*>): String {
return "aaa"
}
}
}
}
class MyTestClass {
val myProvider = MyProvider()
val myField1: String by myProvider
}
//
fun main(args: Array<String>) {
val myTestClass = MyTestClass()
println(myTestClass.myField1)
}
결과 출력:
do something
aaa
println("do something")이 getValue 방법 외에 실행되고 있음을 알 수 있다. 만약에 println("do something") 이 줄 코드가 블로거가 말한 "속성 일치성 검사"코드를 대표한다면 이렇게 하면 블로거가 말한 "확장된 위탁대상의 논리를 실현하고 속성을 만들 때(그 Getter나setter뿐만 아니라) 속성 일치성을 검사한다."
또 하나 주의해야 할 것은provideDelegate라는 방법의 명칭은 함부로 지을 수 없고 이 이름만 사용할 수 있다. 다른 이름을 바꾸면operator 키워드에'operator'modifier is inapplicable on this function:illegal function name;마지막으로 이 코드에 사용된 모델을 설명하자면ReadOnlyProperty는 두 가지 모델을 입력해야 한다. 첫 번째 모델 R은 우리가 get을 원하는 속성이 있는 클래스를 대표하고 두 번째 모델 T는 우리가 get을 원하는 속성의 유형을 의미한다.
꼬리
오늘의 학습 노트는 여기까지입니다. 다음 편에서는 Kotlin의 집합을 계속 공부할 것입니다.낡은 규칙, 나의 문장을 좋아합니다. 환영 소양 3중대: 좋아요, 평론, 관심, 감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
머티리얼 디자인 도입 직후에 할 일
안드로이드 프로젝트에 머티리얼 디자인을 도입한 후에 할 일을 적는다.
Android 프로젝트를 만든 후 Hello world에 대해 수행합니다.
머티리얼 디자인을 도입하기 위해, build.gradle 를 이하와 같...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
머티리얼 디자인 도입 직후에 할 일안드로이드 프로젝트에 머티리얼 디자인을 도입한 후에 할 일을 적는다. Android 프로젝트를 만든 후 Hello world에 대해 수행합니다. 머티리얼 디자인을 도입하기 위해, build.gradle 를 이하와 같...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.