Kotlin基础语法 八、类的属性

一、声明属性

  1. )Kotlin 类中的属性同变量一样既可以用关键字 var 声明为可变的,也可以用关键字 val 声明为不可变的。
    如下:
open class Person {
    val hello = "hello,everyone!"
    var userName = "jf"
    var userAge = 26
}
  1. )类的对象调用一个属性,使用.操作符加属性名称即可。
val person = Person()
person.userName
  1. 类的属性默认是public的,默认情况下public可省略
val hello = "hello,everyone!" 
其实是
public val hello = "hello,everyone!"  //public默认省略

二、Getters 与 Setters

声明一个属性的完整语法如下:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

val <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]

其初始器(initializer)、getter 和 setter 都是可选的。属性类型如果可以从初始器 (或者从其 getter 返回值,如下文所示)中推断出来,也可以省略。
这里我们着重看一下getter 和 setter:
getter 和 setter是什么,getter 和 setter是属性访问器(getter是读访问器,setter是写访问器,因为val是只读变量,所以只有getter访问器),是属性声明的一部分,声明一个属性会默认提供getter和setter,并且我们也可以自定义getter和setter。
getter、setter可以理解为Java中的set()和get()方法

如下:

public class Person {
    private String userName;
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

我们访问一个属性,通过.运算符,它其实就是执行了该属性的getter访问器,如下:我们重写getter访问器,返回一个新的值

open class Person {
    var userName = "jf"
        get() = "真正的用户名称"
    var userAge = 26
}
val person = Person()
Log.e("----",person.userName)

上述代码的运行结果是:
真正的用户名称

类似的,我们给一个属性赋值其实是执行了该属性的setter访问器
如下:

open class Person {
    var userName = "jf"
        set(value) {
        Log.e("执行了setter访问器" , value)
        }
    var userAge = 26
}
val person = Person()
person.userName = "新的用户名"
Log.e("新的用户名",person.userName)

上述代码的运行结果是:
执行了setter访问器: 新的用户名
新的用户名: jf

可以看到上述执行了setter访问器,但我们自定义时没有真正的赋值,所以userName的值还是初始值。

那我们如何自定义setter并完成重新赋值呢?
Kotlin会给setter、getter提供幕后字段,用关键字field表示,幕后字段只能在getter 和setter中访问。
默认的setter访问器其实如下,如果我们自定义的setter访问器如果跟下面一样,编译器就会提示我们去掉

set(value) {
    field = value
}

同样默认的getter访问器如下:

get() = field

所以我们可以通过自定义setter访问器做更多的事,比如在原来的赋值上做数据转换之类的:

open class Person {
    var userName = "jf"
        set(value) {
            field = value.uppercase()
        }
}
val person = Person()
person.userName = "hello world"
Log.e("新的用户名",person.userName)

上述代码的运行结果是:
新的用户名: HELLO WORLD

到此,我们已经会使用幕后字段field了,我们可以进一步理解幕后字段。我们还是以Person类为例,Person类里定义了一个属性userName ,如下:

open class Person {
    var userName = "jf"
}

如果我们将该类转换成Java会是怎么样的呢?如下:

public class Person {
    private String userName= "jf";
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

这已经很清楚了,我们可以这么理解:转换后Java代码中userName其实就是幕后字段,getUserName和setUserName其实就是getter和setter访问器,我们在kotlin中代码中初始化userName就是给Java 中的userName这个幕后字段赋值,在kotlin中代码中访问和赋值userName其实就是调用的Java 中的userName这个幕后字段的getUserName和setUserName方法。

三、幕后属性

一个属性对内为可读可写,对外为只读
如下:

open class Person {
    private var _userAge : Int = 18
    val userAge : Int
        get() = _userAge
}

_userAge属性是private修饰的,因此只有内部可以访问外部不能访问,外部访问userAge属性其实是访问了_userAge属性的值,这种情况下_userAge就是幕后属性。

四、Const 和 Lateinit

Const 声明编译时常数
Lateinit 声明后期初始化属性
我们前面已经讲过了,这里不再重复。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值