ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 类的定义 在面向对象的思想中最核心的就是对象,为了在程序中创建对象,首先需要定义一个类。在定义类时需要使用“class”关键字声明。 类是对象的抽象,它用于描述一组对象的共同特征和行为。类中可以定义成员变量和成员函数,其中成员变量用于描述对象的特征,也被称作属性,成员函数用于描述对象的行为,可简称为函数或方法。 ``` class Person{ //成员属性 private val name = "" private val age = 0 //成员方法 private fun sayHello() { println("我叫${name},我今年${age}岁。") } } ``` ## 类方法和属性的定义 Kotlin定义类、类的成员、类的成员方法和Java很类似。我们通过IDEA提供的java文件转kt文件的功能,直观感受下kotlin定义类和Java定义类的区别。 假设我们有一个Person类,包含name属性和age属性,以及一个printInfo方法,假如我们通过如下Java代码定义Person类,参考代码: ~~~ class Person11 { //成员属性 private String name; private int age; //成员方法 private void printInfo() { System.out.println("我是" + name + ",我今年" + age); } } ~~~ 通过IDE的转换工具,将Java代码转换为kotlin代码,如下所示 ~~~ internal class Person1 { //成员属性 private val name: String? = null private val age: Int = 0 //成员方法 private fun printInfo() { println("我是$name,我今年$age") } } ~~~ 通过这个转换,Kotlin也有private修饰符,Kotlin的成员属性还必须要初始化。 再比如,假如我们通过如下Java代码定义Person类,参考代码: ~~~ class Person2 { //成员属性 private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } private void printInfo() { System.out.println("我是" + name + ",我今年" + age); } } ~~~ 通过IDE的转换工具,将Java代码转换为kotlin代码,如下所示 ~~~ internal class Person2 { //成员属性 var name: String? = null var age: Int = 0 private fun printInfo() { println("我是$name,我今年$age") } } ~~~ 通过转换结果分析,kotlin默认实现了getter和setter方法,属性和方法的默认修饰符是public。 再比如,假如我们通过如下Java代码定义Person类,参考代码: ~~~ class Person33 { //成员属性 protected String name; protected int age; //成员方法 protected void printInfo() { System.out.println("我是" + name + ",我今年" + age); } } ~~~ 通过IDE的转换工具,将Java代码转换为kotlin代码,如下所示 ~~~ internal class Person3 { //成员属性 protected var name: String? = null protected var age: Int = 0 //成员方法 protected fun printInfo() { println("我是$name,我今年$age") } } ~~~ 通过转换结果分析,Kotlin也有protected修饰符。 再比如,假如我们通过如下Java代码定义Person类,参考代码: ~~~ class Person44 { //成员属性 public String name; public int age; //成员方法 public void printInfo() { System.out.println("我是" + name + ",我今年" + age); } } ~~~ 通过IDE的转换工具,将Java代码转换为kotlin代码,如下所示 ~~~ internal class Person4 { //成员属性 var name: String? = null var age: Int = 0 //成员方法 fun printInfo() { println("我是$name,我今年$age") } } ~~~ 通过转换结果分析,和Java写法就没有多大差异了。 ## 类对象的创建、类方法属性的访问 Kotlin创建类对象的时候不需要使用new关键字。类的方法访问和Java访问没区别。类属性访问直接通过点号方式访问,无需在调用getter和setter方法。参考案例: ~~~ class Person { //成员属性 var name = "朵儿" var age = 18 //成员方法 fun printInfo(): Unit { println("我是$name,我今年${age}岁") } } fun main(args: Array<String>) { //创建对象 var person = Person() //调用方法 person.printInfo() //访问属性 println("姓名:${person.name}") //修改属性 person.name = "灵儿" println("姓名:${person.name}") } ~~~ 运行结果 ``` 我是朵儿,我今年18岁 姓名:朵儿 姓名:灵儿 Process finished with exit code 0 ``` 在上述代码中,“Person()”用于创建Person类的实例对象,“var person”则是声明了Person类型的变量person。中间的等号用于将Person对象在内存中的地址赋值给变量person,这样变量person便持有了对象的引用。接下来的章节中为了便于描述变量person引用的对象,通常会将该对象简称为p对象。在内存中变量p和对象之间的引用关系如图所示。 ![](https://img.kancloud.cn/68/87/68873d4d754a36bf231bb5d772a1121c_955x614.png) 在创建Person对象后,可以通过对象的引用来访问对象所有的成员,具体格式如下 ``` 对象引用.对象成员 ``` ## setter、getter(访问器) Kotlin默认帮我们实现了setter、getter,算是setter和getter相关的第一个知识点,除此之外,我们还需要知道setter、getter自定义和setter、getter私有化。 可参考,本系列的另一篇文章[属性与字段](https://www.kancloud.cn/alex_wsc/android_kotlin/1318250#Getters__Setters_49)中讲到的 Getters(读访问器) 与 Setters(写访问器)知识点 ### setter、getter自定义 Kotlin帮我们默认实现了setter和getter,我们也可以对setter和getter自定义,修改获取和设置时候的逻辑。 比如,Student类,包含age属性和name属性,我们对age的setter和getter做一些简单的自定义,参考代码: ~~~ class Student { var name = "小芳" var age = 22 /*-----------自定义get和set------------ */ get() = 18 set(value) { //在赋值的时候提供额外操作 field = value if (value > 18) { println("${name}年龄${age},是成年人") } else { println("${name}年龄${age},是未成年人") } } } fun main(args: Array<String>) { //创建对象 var student = Student() //获取属性 println("${student.name}年龄${student.age}") //修改属性 student.age = 26 } ~~~ 运行结果 ``` 小芳年龄18 小芳年龄18,是成年人 Process finished with exit code 0 ``` 我们可以看到,获取属性的时候,不是默认的“22”了,而是自定义的“18”。设置属性的时候,额外的打印了是否是成年人。 ### setter私有化 kotlin中变量默认访问修饰符是public,对应setter和getter也都是public,如果不想外界修改属性呢?可以显示修饰setter的访问修饰符是private。那么在外部类中,就无法对属性进行修改了。参考案例: ![image.png](http://upload-images.jianshu.io/upload_images/7368752-cf80ff77d877fcc9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 针对以上代码,看到提示了“Cannot assign to ‘name’:the setter isprivate in ‘Person’。也就是,不能对name属性赋值,因为它的setter方法是私有化的。