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 ...
随机推荐
- 解密IP分片与重组:数据传输中的关键技术
引言 在上一章节中,我们详细讨论了IP的分类和无分类原则的原理以及其在网络通信中的应用.IP分片与重组是在数据包传输过程中起到关键作用的机制.当数据包的大小超过网络链路的MTU(最大传输单元)限制时, ...
- fepk文件格式说明
1 卫星影像金字塔分块原理说明 通常我们在工作中使用的卫星影像数据,轻则几百M,重则几百个G甚至上TB级.影像数据太大,是大家经常会遇到的一个问题,尤其是想下载一个省以上数据的时候该问题尤为突出.那 ...
- C++ 对拍详解 和解读
对拍是什么# 对拍,是一个比较实用的工具.它能够非常方便地对于两个程序的输出文件进行比较,可以帮助我们实现一些自动化的比较输出结果的问题. 众所周知,几乎每一道编程题目,都会有某种正解能拿到满分: ...
- Linux系列教程——Shell、Linux文件管理
文章目录 Shell 1.什么是Bash shell(壳) 2.Bash Shell能干什么? 3.平时我们如何使用Shell呢? 4.Shell提示符 5.Shell基础语法 2.Bash Shel ...
- 形象描绘TCP三次握手和四次挥手
一.TCP三次握手TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己.形象描绘TCP三次握手和四次挥手 张三首先向 ...
- Visible Lattice Points 题解
Visible Lattice Points 题目大意 给定一个 \(N×N×N\) 的由若干点组成的立方体,点的坐标从 \((0,0,0)\) 到 \((N,N,N)\),求从点 \((0,0,0) ...
- Memcached的基本操作
一.Memcache使用场景1.非持久化存储:对数据存储要求不高2.分布式存储:不适合单机使用3.key/value存储:格式简单,不支持list,array数据格式二.系统类$m=new Memca ...
- 当我们输入 kubectl run 时都发生了什么?
为了确保整体的简单性和易上手,Kubernetes 通过一些简单的抽象隐去操作背后的复杂逻辑,但作为一名有梦想的工程师,掌握其背后的真正思路是十分有必要的.本文以 Kubectl 创建 Pod 为例, ...
- C#winform软件实现一次编译,跨平台windows和linux兼容运行,兼容Visual Studio原生界面Form表单开发
一.背景: 微软的.net core开发工具,目前来看,winform界面软件还没有打算要支持linux系统下运行的意思,要想让c#桌面软件在linux系统上运行,开发起来还比较麻烦.微软只让c#的控 ...
- centos7通过yum安装mysql5.7以上版本
1.检查并卸载mariadb yum remove *mariadb* 遇到要求输入直接y/n 直接输入y回车 2.下载并安装mysql mysql源地址:https://repo.mysql.com ...