Kotlin委托属性(1)
在Kotlin中,委托属性(Delegated Properties)是一种强大的语言特性,允许你将属性的 getter 和 setter 方法的实现委托给其他对象。这使得你能够通过委托来重用代码、将属性的行为解耦,并实现一些通用的模式。下面是一些关键概念和用法:
- class Example {
- var property: String by Delegate()
- }
- class Delegate {
- operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
- // 获取属性值的实际实现
- return "Delegated value"
- }
- operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
- // 设置属性值的实际实现
- println("Setting value to: $value")
- }
- }
在上面的代码中,Example类中的property属性的访问,比如,访问example.property,就会委托到Delegate.getValue; 属性值的设置example.property = "str",就会委托到
Delegae.setValue。
实际例子:
- fun saveCookie(url: String?, domain: String?, cookies: String) {
- url ?: return
- var spUrl: String by Preference(url, cookies)
- @Suppress("UNUSED_VALUE")
- spUrl = cookies
- domain ?: return
- var spDomain: String by Preference(domain, cookies)
- @Suppress("UNUSED_VALUE")
- spDomain = cookies
- }
var spUrl: String by Preference(url, cookies),定义一个委托属性spUrl,Preference委托,执行spUrl = cookies,会将这个setValue的动作委托到Preference类中的setValue。
- operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
- putSharedPreferences(name, value)
- }
其中value的值是cookies.如果要访问spUrl,那么,对应的getValue方法,会被委托到Preference中的getValue方法中去。
总结来说:
委托属性,就是将一个属性的getValue方法和setValue方法委托到另外一个代理类来实现。将属性的获取和设置隔离开来。
- class Preference<T>(val name: String, private val default: T) {
- companion object {
- private val file_name = "wan_android_file"
- private val prefs: SharedPreferences by lazy {
- App.context.getSharedPreferences(file_name, Context.MODE_PRIVATE)
- }
- /**
- * 删除全部数据
- */
- fun clearPreference() {
- prefs.edit().clear().apply()
- }
- /**
- * 根据key删除存储数据
- */
- fun clearPreference(key: String) {
- prefs.edit().remove(key).apply()
- }
- /**
- * 查询某个key是否已经存在
- *
- * @param key
- * @return
- */
- fun contains(key: String): Boolean {
- return prefs.contains(key)
- }
- /**
- * 返回所有的键值对
- *
- * @param context
- * @return
- */
- fun getAll(): Map<String, *> {
- return prefs.all
- }
- }
- operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
- return getSharedPreferences(name, default)
- }
- operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
- putSharedPreferences(name, value)
- }
- @SuppressLint("CommitPrefEdits")
- private fun putSharedPreferences(name: String, value: T) = with(prefs.edit()) {
- when (value) {
- is Long -> putLong(name, value)
- is String -> putString(name, value)
- is Int -> putInt(name, value)
- is Boolean -> putBoolean(name, value)
- is Float -> putFloat(name, value)
- else -> putString(name, serialize(value))
- }.apply()
- }
- @Suppress("UNCHECKED_CAST")
- private fun getSharedPreferences(name: String, default: T): T = with(prefs) {
- val res: Any = when (default) {
- is Long -> getLong(name, default)
- is String -> getString(name, default) ?: ""
- is Int -> getInt(name, default)
- is Boolean -> getBoolean(name, default)
- is Float -> getFloat(name, default)
- else -> deSerialization(getString(name, serialize(default)) ?: "")
- }
- return res as T
- }
- /**
- * 序列化对象
- * @param person
- * *
- * @return
- * *
- * @throws IOException
- */
- @Throws(IOException::class)
- private fun <A> serialize(obj: A): String {
- val byteArrayOutputStream = ByteArrayOutputStream()
- val objectOutputStream = ObjectOutputStream(
- byteArrayOutputStream
- )
- objectOutputStream.writeObject(obj)
- var serStr = byteArrayOutputStream.toString("ISO-8859-1")
- serStr = java.net.URLEncoder.encode(serStr, "UTF-8")
- objectOutputStream.close()
- byteArrayOutputStream.close()
- return serStr
- }
- /**
- * 反序列化对象
- * @param str
- * *
- * @return
- * *
- * @throws IOException
- * *
- * @throws ClassNotFoundException
- */
- @Suppress("UNCHECKED_CAST")
- @Throws(IOException::class, ClassNotFoundException::class)
- private fun <A> deSerialization(str: String): A {
- val redStr = java.net.URLDecoder.decode(str, "UTF-8")
- val byteArrayInputStream = ByteArrayInputStream(
- redStr.toByteArray(charset("ISO-8859-1"))
- )
- val objectInputStream = ObjectInputStream(
- byteArrayInputStream
- )
- val obj = objectInputStream.readObject() as A
- objectInputStream.close()
- byteArrayInputStream.close()
- return obj
- }
- }
Kotlin委托属性(1)的更多相关文章
- kotlin委托属性
fun main(arg: Array<String>) { val myClass1 = myClass1() myClass1.name="mycalsss1" v ...
- ViewBinding 与 Kotlin 委托双剑合璧
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭 ...
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
作者:Antonio Leiva 时间:Mar 9, 2017 原文链接:https://antonioleiva.com/property-delegation-kotlin/ 如我们在前面文章中读 ...
- kotlin 委托
委托模式是软件设计模式中的一项基本技巧.在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理. Kotlin 直接支持委托模式,更加优雅,简洁.Kotlin 通过关键 ...
- Kotlin 委托(1)类委托、变量委托注意事项
1.官方文档 英文: https://kotlinlang.org/docs/reference/delegation.html https://kotlinlang.org/docs/referen ...
- Kotlin代理属性--官方文档翻译
代理属性 Delegated Properties 本文为个人翻译的Kotlin官方文档, 原文连接: Delegated Properties 一些特定的常见类型的属性, 尽管我们可以在每次需要的时 ...
- Kotlin 委托(2)变量委托是什么、自定义变量委托
1.委托是什么? 1.1 官网示例 在每个变量委托的实现的背后,Kotlin 编译器都会生成辅助对象并委托给它. 假设委托如下, class C { var prop: Type by MyDeleg ...
- python cookbook第三版学习笔记十七:委托属性
我们想在访问实例的属性时能够将其委托到一个内部持有的对象上,这经常用到代理机制上 class A: def spam(self,x): print("class_A: ...
- kotlin 委托类的初始化函数
import java.beans.AppletInitializer import kotlin.reflect.KProperty fun main(arg: Array<String> ...
- Android kotlin静态属性、静态方法
只需要用 companion object 包裹相应代码块即可.以静态属性为例: class Constants { companion object { val BASE_URL = "h ...
随机推荐
- pyinstall打包相对路径问题
pyinstall打包相对路径问题 pyinstaller 打包py文件成exe文件,在没有python的机器上运行,执行打包后的程序,经常会出现程序使用的图标无法显示,程序使用的关联文件无法关联 ...
- JAVA动态增强一个BaseController的已经存在的接口
使用场景 前提场景 我们多个系统同时继承了某一个通用系统,通用系统的接口是不会允许随意改变的,其他子系统都依赖于Base系统的通用接口 目标需求场景 但是有一个业务,需要给某一个公共接口增加子系统独有 ...
- c语言代码练习4(改进)
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <wi ...
- frida动态插桩初探
前言 近期碰到了分析app的需求,就学习了一下 frida的动态插桩技术.frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.frida分为两部分,服务端 ...
- Maximum Diameter 题解
Maximum Diameter 题目大意 定义长度为 \(n\) 的序列 \(a\) 的权值为: 所有的 \(n\) 个点的第 \(i\) 个点的度数为 \(a_i\) 的树的直径最大值,如果不存在 ...
- 数据结构-线性表-顺序表(c++)
SeqList.h #ifndef SEQLIST_H_ #define SEQLIST_H_ #include<iostream> const int Max=100; template ...
- 如何在Notepad++中轻松删除包含指定文本的字符串
如果你需要在大量文本中删除指定模式的字符串,可以使用Notepad++中的正则表达式功能.下面是一个示例,让你可以快速学会如何删除包含指定文本的字符串.我们将使用以下示例字符串: This is a ...
- adb从基础到进阶
一.adb的工作原理 adb是cs架构,由三部分组成,分别是client,server,daemon,他们的关系见下图 server是整个架构的核心 server负责接收client的指令,然后将指令 ...
- python之继承的方法重写
目录 普通方法 方法重写super().xxx() 我们在python之继承及其实现方法中已经学会了打印子类在父类继承的属性 那么我们怎么打印出子类中特有的属性呢 普通方法 我们当然可以在子类中添加新 ...
- 小心C#中的只读结构体成员
示例 我们先来看一段结构体的代码 (基于 VS2022 + .NET 8.0) public struct MyStruct(int number) { public int Number = num ...