news 2026/5/1 10:48:58

Kotlin类代码实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kotlin类代码实战

用一段示例代码来讲解下kotlin的类,讲一下每一部分在干什么、为什么这么写,以及它们之间的关系。


1. 基类SmartDevice

openclassSmartDevice(valname:String,valcategory:String){vardeviceStatus="online"protectedsetopenvaldeviceType="unknown"openfunturnOn(){deviceStatus="on"}openfunturnOff(){deviceStatus="off"}}

关键点:

  1. open class

    • Kotlin 中类默认是final,不能被继承。
    • open表示:允许其他类继承它。
  2. 构造函数参数直接变成属性

    valname:String,valcategory:String

    等价于在类里声明只读属性namecategory并在构造时赋值。

  3. deviceStatus+protected set

    vardeviceStatus="online"protectedset
    • 外部代码可以读取deviceStatus
    • 但只有这个类和子类可以修改它(protected set),外部不能做deviceStatus = "xxx"
    • 这样可以保护状态,只允许通过turnOn()/turnOff()之类的方法来改变。
  4. open val deviceTypeopen fun turnOn/turnOff

    • 表示子类可以override它们,做出更具体的实现。

2. 子类SmartTvDevice

classSmartTvDevice(deviceName:String,deviceCategory:String):SmartDevice(name=deviceName,category=deviceCategory){overridevaldeviceType="Smart TV"privatevarspeakerVolumebyRangeRegulator(initialValue=2,minValue=0,maxValue=100)privatevarchannelNumberbyRangeRegulator(initialValue=1,minValue=0,maxValue=200)funincreaseSpeakerVolume(){speakerVolume++println("Speaker volume increased to$speakerVolume.")}funnextChannel(){channelNumber++println("Channel number increased to$channelNumber.")}overridefunturnOn(){super.turnOn()println("$nameis turned on. Speaker volume is set to$speakerVolumeand channel number is "+"set to$channelNumber.")}overridefunturnOff(){super.turnOff()println("$nameturned off")}}

要点:

  1. 继承写法

    classSmartTvDevice(...):SmartDevice(name=deviceName,category=deviceCategory)
    • 冒号:表示继承。
    • 括号里是父类构造函数的参数
  2. override val deviceType

    • 覆盖父类的deviceType,让电视设备显示为"Smart TV"
  3. speakerVolume/channelNumber使用委托属性

    privatevarspeakerVolumebyRangeRegulator(...)
    • by关键字表示属性委托(delegated property)。
    • RangeRegulator实现了ReadWriteProperty<Any?, Int>,因此可以接管这个属性的get/set行为。
    • 这里的效果:音量、频道的值会被自动限制在指定区间内(0…100、0…200)。
  4. override fun turnOn()

    • super.turnOn(),保持父类的通用逻辑(把deviceStatus改成"on")。
    • 再打印这个设备特有的信息(音量和频道)。

3. 子类SmartLightDevice

classSmartLightDevice(deviceName:String,deviceCategory:String):SmartDevice(name=deviceName,category=deviceCategory){overridevaldeviceType="Smart Light"privatevarbrightnessLevelbyRangeRegulator(initialValue=0,minValue=0,maxValue=100)funincreaseBrightness(){brightnessLevel++println("Brightness increased to$brightnessLevel.")}overridefunturnOn(){super.turnOn()brightnessLevel=2println("$nameturned on. The brightness level is$brightnessLevel.")}overridefunturnOff(){super.turnOff()brightnessLevel=0println("Smart Light turned off")}}

逻辑类似电视设备,只是属性换成了亮度brightnessLevel,并用同样的RangeRegulator控制取值范围。


4.SmartHome聚合多个设备

classSmartHome(valsmartTvDevice:SmartTvDevice,valsmartLightDevice:SmartLightDevice){vardeviceTurnOnCount=0privatesetfunturnOnTv(){deviceTurnOnCount++smartTvDevice.turnOn()}funturnOffTv(){deviceTurnOnCount--smartTvDevice.turnOff()}funincreaseTvVolume(){smartTvDevice.increaseSpeakerVolume()}funchangeTvChannelToNext(){smartTvDevice.nextChannel()}funturnOnLight(){deviceTurnOnCount++smartLightDevice.turnOn()}funturnOffLight(){deviceTurnOnCount--smartLightDevice.turnOff()}funincreaseLightBrightness(){smartLightDevice.increaseBrightness()}funturnOffAllDevices(){turnOffTv()turnOffLight()}}

要点:

  1. SmartHome不继承任何设备,而是组合(Has-a)

    • 拥有SmartTvDeviceSmartLightDevice两个属性。
    • 这就是“聚合 / 组合”的关系:家里有一个电视和一个灯。
  2. deviceTurnOnCount+private set

    • 对外暴露统计信息,但不允许外部随意修改计数,只能通过这些方法递增 / 递减。
  3. 提供一组高层方法

    • turnOnTv()turnOnLight()等,相当于对内部设备进行“统一控制”,这是典型的「封装」和「门面/facade」模式。

5. 属性委托类RangeRegulator

classRangeRegulator(initialValue:Int,privatevalminValue:Int,privatevalmaxValue:Int):ReadWriteProperty<Any?,Int>{varfieldData=initialValueoverridefungetValue(thisRef:Any?,property:KProperty<*>):Int{returnfieldData}overridefunsetValue(thisRef:Any?,property:KProperty<*>,value:Int){if(valueinminValue..maxValue){fieldData=value}}}

这是整个示例中最“高级”的部分:自定义属性委托

  1. ReadWriteProperty<Any?, Int>

    • 来自kotlin.properties,是一个接口:
      interfaceReadWriteProperty<inR,T>{operatorfungetValue(thisRef:R,property:KProperty<*>):ToperatorfunsetValue(thisRef:R,property:KProperty<*>,value:T)}
    • R是“拥有这个属性的对象”的类型;这里用Any?,表示不关心谁在用它。
    • T是属性类型,这里是Int
  2. fieldData保存真正的值。

    • 所有对speakerVolume/brightnessLevel的读写,最终都落在fieldData上。
  3. setValue中做范围检查:

    if(valueinminValue..maxValue){fieldData=value}
    • 只有新值在合法范围内时才更新。
    • 如果超出范围,会被默默忽略(可以根据需求改成抛异常、裁剪值等)。

效果:你在类里写的代码只是:

speakerVolume++// 看起来就是普通 IntbrightnessLevel=2000// 实际上不会被设置,超出范围

但背后逻辑已经被RangeRegulator统一接管了,达到“逻辑复用 + 解耦”的目的。


6. 多态的使用:SmartDevice引用指向不同子类

funmain(){varsmartDevice:SmartDevice=SmartTvDevice("Android TV","Entertainment")smartDevice.turnOn()smartDevice=SmartLightDevice("Google Light","Utility")smartDevice.turnOn()}
  • 变量类型是父类SmartDevice,但实际对象是不同的子类:
    1. 先指向SmartTvDevice
    2. 后指向SmartLightDevice
  • 调用smartDevice.turnOn()时,会根据实际类型调用对应子类的重写方法,这就是多态 (polymorphism)

你会看到输出先是电视开机的信息,再是灯开灯的信息。


7. 这个示例体现的 Kotlin / OOP 概念

示例刚好涵盖了:

  1. class / open class / 继承 / override
  2. 主构造函数 + 属性简写 (val name: String)
  3. 访问控制:private/protected set/private set
  4. 封装与组合(SmartHome拥有多个设备)
  5. 多态(父类引用指向子类实例)
  6. 属性委托(by RangeRegulator+ReadWriteProperty
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:49:21

基于SpringBoot的医院人事管理系统的设计与实现毕业设计项目源码

题目简介在医疗行业规范化发展、医院人员规模扩大的背景下&#xff0c;传统人事管理存在 “信息分散、流程繁琐、权限管控模糊、数据统计滞后” 的痛点。基于 SpringBoot 构建的医院人事管理系统&#xff0c;适配人事管理员、科室主任、医护人员、行政人员等角色&#xff0c;实…

作者头像 李华
网站建设 2026/5/1 7:51:47

第八课 Open3D点云数据处理:统计滤波

1 统计滤波原理 2 参数说明 2.1 返回滤波后的点云和对应的索引 2.2 提取滤波后的点云&#xff08;内点&#xff09; 2.3 提取噪声点云&#xff08;外点&#xff09; 3 代码实现 3.1 直接编写代码行 3.2 封装为函数 1 统计滤波原理 三维点云统计滤波&#xff08;Statist…

作者头像 李华
网站建设 2026/5/1 7:51:51

Leetcode 25. K 个一组翻转链表 JavaScript (Day 12)

js一刷自解 var reversefunction(node0,head,k){let rearhead;let curhead;for(let i0;i<k;i){let tempcur.next;let node1node0.next;node0.nextcur;cur.nextnode1;curtemp;}rear.nextcur;return[rear,cur]; }var reverseKGroup function(head, k) {let dummynew ListNod…

作者头像 李华
网站建设 2026/5/1 6:48:12

Leetcode 138. 随机链表的复制 (Day 12)

js 一刷 var copyRandomList function(head) {if (!head) return null;let map new Map();let cur head;while (cur) {map.set(cur, new ListNode(cur.val));cur cur.next;}cur head;while (cur) {let copy map.get(cur);copy.next map.get(cur.next) ?? null;copy.ra…

作者头像 李华
网站建设 2026/5/1 8:59:54

基于Java+SpringBoot的零售与仓储管理系统(源码+lw+部署文档+讲解等)

课题介绍 本课题聚焦零售行业与仓储管理脱节、库存周转效率低、订单处理流程繁琐、数据协同不及时等痛点&#xff0c;设计并实现一款基于JavaSpringBoot的零售与仓储管理系统&#xff0c;旨在打通零售端与仓储端数据链路&#xff0c;为企业提供一体化的经营管理解决方案。系统以…

作者头像 李华
网站建设 2026/4/30 23:31:31

深度学习计算机毕设之基于python的人脸识别系统设计与实现机器学习

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华