6.类(2)--类的成员

.成员定义

   类的成员包括:字段、方法和属性,所有成员都有自己的访问级别,包括:

         public -------->成员可以由任何代码访问

         private ---->默认类型,成员只能由类中的代码访问

         internal ---->成员只能由定义它的程序集(项目)内部的代码访问

         portected --->成员只能由类或派生类中的代码访问

         static ---->表示类的静态成员,只能由类来访问,不能由类的实例访问

1.定义字段

   标准变量声明格式即可,但有如下注意事项:

    1).公共字段用PascalCasing形式命名

    2).除上述访问控制字符外,还可以结合如下两个关键字:

         readonly ---->字段只能在执行构造函数的过程中赋值或由初始化赋值语句赋值

         static --------->静态字段,该字段只能由类访问,不能用类的对象访问

         const --------->常量

2.定义方法

  标准的函数声明格式、可访问性和可选的修饰符

    1).公共方法也用PascalCasing格式命名

    2).可选关键字如下:

         virtual --->方法可以重写

         abstract --->方法必须在非抽象的派生类中重写(只用于抽象)

         override ---->方法重写了一个基类的方法(必须)

         extern ----->方法定义放在其他地方

         override sealed----->子类中不能对这个方法作进一步修改

3.定义属性

   定义方式与字段类似,但里面用访问器

   1.属性可以使用virtualoverrideabstract关键字

   2.访问器也可以有自己的可访问性,但访问器的访问级别不能高于包含该属性的类的访问几倍

 3.get和set块可以拥有单独的访问级别

.类成员的其他主题

1.重写方法

 继承类使用与父类方法名相同的方法,但方法内容不同

2.隐藏方法

   new关键字隐藏来自基类的方法

 注:new关键字不能与overral修饰同一个方法

3.调用重写或隐藏的基类方法

   basethis关键字

4.嵌套的类型定义

 类除了可以定义在命名空间中外,还可以定义在其他类中

.接口的实现

 1.接口的定义与类的定义相似,但接口成员与类成员却又如下区别:

  1>.所有接口成员都是隐式的公共的,不能用publicprivateprotectedinternal

  2>.接口成员不能包含代码体

  3>.接口不能定义字段成员

  4>.不能用关键字 staticvirtualabstractsealed来定义接口成员

  5>.类型定义成员是被禁止的

  6>.隐藏从基类接口中继承的成员,用关键字new

  7>.接口可以成为类的成员,但类和接口不能成为接口的成员

2.在类中实现接口

    1>.实现接口的类必须包含该接口所有成员的实现代码,且必须匹配指定的签名

    2>.类必须是公共public

    3>.可以使用关键字virtualabstruct来实现接口成员,但不能使用staticconst

    4>.还可以在基类上实现接口。继承了一个实现了接口的基类,子类隐式的支持该接口

    5>.接口成员中包括属性,则必须实现匹配get/set存取器。且存取器的修饰符必须是比接口中已经定义的修饰符更严格的修饰符

.部分类定义

    把一个类定义拆分成多个模块,用partial关键字。如可以把所有字段放在一个部分、把所有属性放在一个部分等。

     1>.部分定义的类名是一样的

     2>.如果类是继承自某基类的子类,则部分类定义是基类名称是一致的。因为子类只能有一个基类

     3>.部分类实现不同的接口,与类实现所有接口是等价的

.部分方法定义

    方法也可以分部分用partial定义,同一个方法在A部分中只有方法名,在B部分中有方法体


是的,**你可以在方法中这样声明 `var ssid = when(...) { ... }`**,而且 **`when` 里面的 `ssid`(比如 `_5gSsid`、`_6gSsid`)可以正确引用成员变量**,只要它们是可访问的(如 `private`、`public` 或默认可见性)。 --- ### ✅ 你的代码是否合法? ```kotlin var ssid = when(connType) { WIRELESS_TYPE._2_4G -> ssid // ⚠️ 这里有问题!见下文 WIRELESS_TYPE._5G -> _5gSsid else -> _6gSsid } ``` #### 🔍 分析: | 行为 | 是否可行 | |------|----------| | `WIRELESS_TYPE._5G -> _5gSsid` | ✅ 正确:引用的字段 `_5gSsid` | | `else -> _6gSsid` | ✅ 正确:同上 | | `WIRELESS_TYPE._2_4G -> ssid` | ❌ **问题:这里用的是自己(局部变量)** | > ❗ 关键问题就出在这里: ```kotlin -> ssid ``` 这个 `ssid` 是你正在声明的 **局部变量本身**,不是的字段! 由于 Kotlin 允许在初始化时使用同名变量,这会导致: - 局部变量 `ssid` 被赋值为它自己(未初始化),结果可能是 `null` 或意外值。 - 实际上形成了“自引用”,逻辑错误。 --- ### ✅ 正确做法:明确区分局部变量和成员 假设你的中有如下字段: ```kotlin class WifiConfigFragment : Fragment() { private var ssid: String = "" // 成员变量 private var _5gSsid: String = "" private var _6gSsid: String = "" fun someMethod(connType: WIRELESS_TYPE) { val currentSsid = when(connType) { WIRELESS_TYPE._2_4G -> this.ssid // 明确使用 this 指向成员 WIRELESS_TYPE._5G -> _5gSsid // 直接访问成员 else -> _6gSsid } // 使用 currentSsid ... } } ``` --- ### ✅ 解决方案总结 #### ✅ 方案一:使用 `this` 区分成员变量(推荐) ```kotlin val ssid = when(connType) { WIRELESS_TYPE._2_4G -> this.ssid WIRELESS_TYPE._5G -> this._5gSsid else -> this._6gSsid } ``` 👉 使用 `this.ssid` 明确表示“成员变量”,避免与局部变量混淆。 --- #### ✅ 方案二:改名局部变量(更清晰) ```kotlin val selectedSsid = when(connType) { WIRELESS_TYPE._2_4G -> ssid WIRELESS_TYPE._5G -> _5gSsid else -> _6gSsid } ``` 即使不加 `this`,Kotlin 在方法内访问的属性时会自动解析为成员变量(前提是无冲突命名)。所以这里的 `ssid` 会被识别为成员。 但为了清晰起见,建议加上 `this.`。 --- ### 📝 注意事项 | 要点 | 说明 | |------|------| | ✅ 成员变量可在方法中直接访问 | 只要可见性允许(private 也可在内部访问) | | ✅ `when` 中可以引用成员 | 如 `_5gSsid` 是完全合法的 | | ⚠️ 避免局部变量与成员同名 | 容易引起歧义或错误引用 | | ✅ 推荐使用 `this.xxx` 明确作用域 | 提高可读性和安全性 | --- ### ✅ 最佳实践示例 ```kotlin class NetworkSettingsViewModel : ViewModel() { var ssid: String = "HomeWiFi" var _5gSsid: String = "HomeWiFi_5G" var _6gSsid: String = "HomeWiFi_6G" fun getSsidByType(connType: WIRELESS_TYPE): String { return when (connType) { WIRELESS_TYPE._2_4G -> this.ssid WIRELESS_TYPE._5G -> this._5gSsid else -> this._6gSsid } } } ``` --- ### ✅ 总结 > - ✔️ 你可以在方法中使用 `var/val ssid = when(...) { ... }` 声明新变量; > - ✔️ `when` 中的 `_5gSsid`、`_6gSsid` 能正确获取成员的值; > - ❌ 但不要写成 `-> ssid`,否则会引用到正在初始化的局部变量,造成逻辑混乱; > - ✅ 正确做法是使用 `this.ssid` 或改名局部变量来避免冲突。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值