Kotlin笔记 第七章 (一)类.md
类
1.定义
[修饰符] class 类名 [constructor 主构造器]{
0~N个次构造器
0-N个属性
0-N个方法
}
空类:没有类体,可以省略大括号
如:class EmptyClass
1.1、修饰符
类修饰符:
public、internal、private(只能出现其一),final、Open、abstract(只能出现其一)
构造器修饰符:
public、protected、internal、private
2、构造器
格式:
[修饰符] constructor(形参列表){
}
修饰符:可以省略,也可以是public、protected、internal、private其中之一
分为主构造器和次构造器,一个类可以有01个主构造器,0N个次构造器
主构造器:紧跟在类名后,
- 使用关键字"constructor"
- 无执行体,但可以有多个形参,可以在属性声明、初始化块中使用
- 如果构造器没有任何修饰符或注解可以省略"constructor"关键字
如:
class Person constructor(age:int,name:String){
}
主构造器的参数,可以在属性声明、初始化块中使用;
如果没有为非抽象类提供任何主、次构造器,系统默认会提供一个无参的主构造器,默认修饰符public;但是一旦程序员为类提供了一个构造器,系统将不会为类提供默认构造器
3、属性
Kotlin中的属性相当于java中的字段(成员变量)、setter()、getter()方法
格式:
[修饰符] var|val 属性名:类型=[默认值]
[getter方法]
[setter方法]
修饰符可以使public|protected|internal|private、final|open|abstract两部分都只能出现其一
关于函数多说一点:如果是定义在类中的函数,可以使用以上修饰符修饰,但是直接定义在.kt文件中(类外面)的*函数,不能使用protected、abstract|fianl修饰
定义val(只读字段),系统会为它生成public final修饰的getter方法,定义var字段,会自动生成getter和setter方法;这些成员属性变量,需要程序员显示指定初始值,要么在定义时指定初始值,要么在构造器中指定初始值,Kotlin中定义的属性相当于java中private修饰的field.
3.1、自定义getter、setter方法
在定义属性时,可以指定自定义的getter、setter方法,在这些方法中加入自己的控制逻辑;
getter方法:是形如get(){}方法,无参、待返回值
setter方法:是一个形如set(value){}的方法,带一个参数、无返回值的方法
自定义getter、setter方法无须使用fun关键字
如:
class User {
var first:String="lin"
var last:String="leslie"
val fullName:String
get() = "${first}.${last}"
}
这里对只读fullName重写了了getter方法,因此该属性没有幕后字段(下面就会讲到),Kotlin不允许为该属性指定初始值。该属性是通过上面两个属性计算出来的,Kotlin不需要为它生成对应的feild,他不需要真正的存储状态;
如果只需要改变getter或者setter方法的可见性或者对其添加注解,不需要改变其默认实现,可以自定义getter或者setter方法名,而不用重新定义其代码实现;
如:
class User{
var foo:String="abc"
private set
var bar:Int?=null
@inject set
}
3.2、幕后字段
普通属性,kotlin会生成一个field(字段)、setter()(只读属性没有)、getter()方法,生成的field就叫做幕后字段,Kotlin要求为该属性显示指定初始值,要么在定义时就指定,要么在构造器中指定;
如果没有幕后字段,则不允许为该属性指定初始值(因为没有field,没有地方保存)
那些时候会为属性生成幕后字段呢?
- 只读属性必须重写getter()方法,读写属性必须重写setter()、getter()方法,否则会为该属性生成幕后字段
- 重写getter()或者setter()方法时 使用field关键字引用幕后字段
3.3、属性延迟初始化
Kotlin要求所有属性必须显示初始化,前面我们说了 要么在声明时初始化,要么在构造器中初始化。但有时候,这不是必须的。如通过依赖注入为属性初始化,或者在单元测试的setUp()方法初始化
通过使用"lateinit"修饰符修饰属性,延迟初始化(就可以不在定义属性或构造器中初始化)
但对可以使用"lateinit"修饰符修饰的属性有要求:
- lateinit只能修饰类体中的声明的可变属性(val声明的属性不行,在主构造器中声明的属性也不行)
- 修饰的属性不能有自定义的setter()或者getter()方法
- 属性必须是非空类型(不能是String?这种类型)
- 属性不能是原生类型(即Java8对应的8种基本类型对应的类型)
Kotlin不会像Java为属性默认初始化,一旦在赋初始值前访问该属性,就会报"延迟属性还未初始化异常"
3.4、内联属性
说内联属性之前,我们可以先回忆一下内联函数:
高阶函数:(为函数传入函数或者lambda表达式作为参数)
其调用过程:
- 程序将执行顺序转移到被调用函数或者lambda表达式所在的内存地址
- 当被调用的表达式或者函数执行完后,再回到原函数执行的地方
内联函数:使用inline关键字修饰带函数形参的函数即可;其实质就是讲被调用函数或者Lambda表达式函数体代码复制粘贴到调用函数中
内联属性要求:
- 该属性没有幕后字段
可以修饰属性的getter或者setter方法,或者修饰属性本身(表示同时修饰setter、getter方法)
和内联函数一样,在执行getter或者setter方法是会执行内联化
方法
Kotlin中方法和函数区别:
方法:指定定义在类中的函数
函数:
方法修饰符:public、protected、internal、private、final、abstract、open
函数修饰符:不能使用protected、abstract、final修饰
数据类
Kotlin提供的一种特殊的类,专门用于封装数据。
推荐阅读
-
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
-
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
-
Ruby简洁学习笔记(一):字符串、数字、类和对象
-
C++笔记一(创建一个不带指针成员变量的类)[注意事项]
-
python学习笔记:第19天 类的约束、异常、MD5和logging
-
20.7.17 笔记算数运算符 复合运算符重载 比较运算重载 多态 设计原则 类的单一职责 依赖倒置 组合复用原则 里氏替换 迪米特法则 矩阵转置原理
-
Python 学习笔记(十四)Python类(一)
-
C#学习笔记——类的一个例子
-
【JAVASE学习笔记之File类、递归】:IO系列(一)
-
Python 学习笔记(十五)Python类拓展(一)继承