如何正确访问类属性并实现类变量的合规存储与封装?
类属性封装:两种方案的适用场景分析
你提到的两种写法都是Kotlin中实现封装的常用方式,没有绝对的“正确”,核心区别在于你想给外部代码暴露的读写权限,以及对内部状态的控制程度:
1. 公开var + 自定义get/set(带field)
这种方案适用于需要让外部既能读取又能修改属性,但希望对修改行为做控制的场景:
- 外部代码可以直接通过
beds读写,但写入时会经过你定义的set逻辑(比如校验值的合法性、触发状态更新等) - 内部的
field是Kotlin的关键字,代表属性的幕后字段,外部代码完全看不到它,只感知到公开的beds属性 - 比如你可以在set里加入校验,防止设置负数的床数量:
class SleepingRoom { var beds = 2 set(value) { if (value >= 0) { field = value } else { throw IllegalArgumentException("床的数量不能为负数") } } }
2. private幕后字段 + 公开val
这种方案适用于只允许外部读取属性,不允许直接修改的场景:
- 外部只能通过
beds2读取值,无法直接赋值(因为beds2是val),所有对属性的修改必须由类内部的方法或逻辑完成 - 私有
_beds2完全隐藏在类内部,外部无法访问,最大程度保证了内部状态的可控性 - 比如你可以给类添加方法来控制床的数量变化,确保逻辑统一:
class SleepingRoom { private var _beds2 = 2 val beds2: Int get() = _beds2 fun addBed() { _beds2 += 1 } fun removeBed() { if (_beds2 > 0) { _beds2 -= 1 } } }
关于“外部知晓内部属性”的顾虑
不管哪种方案,外部代码只需要知道你公开的属性名(beds或beds2),完全不需要关心类内部的实现细节:
- 第一种方案的
field是Kotlin的幕后字段语法,外部不可见 - 第二种方案的
_beds2是私有变量,外部也无法访问
两者都实现了封装,只是暴露的权限范围不同。你只需要根据业务需求选择:需要外部可写就用第一种,只允许外部只读就用第二种。
内容的提问来源于stack exchange,提问作者Pferdesalbe
相关产品推荐
相关产品推荐

