欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Kotlin笔记 第七章 (一)类.md

程序员文章站 2022-03-13 10:48:41
...

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个次构造器

主构造器:紧跟在类名后,

  1. 使用关键字"constructor"
  2. 无执行体,但可以有多个形参,可以在属性声明、初始化块中使用
  3. 如果构造器没有任何修饰符或注解可以省略"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,没有地方保存)

那些时候会为属性生成幕后字段呢?

  1. 只读属性必须重写getter()方法,读写属性必须重写setter()、getter()方法,否则会为该属性生成幕后字段
  2. 重写getter()或者setter()方法时 使用field关键字引用幕后字段

3.3、属性延迟初始化

Kotlin要求所有属性必须显示初始化,前面我们说了 要么在声明时初始化,要么在构造器中初始化。但有时候,这不是必须的。如通过依赖注入为属性初始化,或者在单元测试的setUp()方法初始化

通过使用"lateinit"修饰符修饰属性,延迟初始化(就可以不在定义属性或构造器中初始化)

但对可以使用"lateinit"修饰符修饰的属性有要求:

  1. lateinit只能修饰类体中的声明的可变属性(val声明的属性不行,在主构造器中声明的属性也不行)
  2. 修饰的属性不能有自定义的setter()或者getter()方法
  3. 属性必须是非空类型(不能是String?这种类型)
  4. 属性不能是原生类型(即Java8对应的8种基本类型对应的类型)

Kotlin不会像Java为属性默认初始化,一旦在赋初始值前访问该属性,就会报"延迟属性还未初始化异常"

3.4、内联属性

说内联属性之前,我们可以先回忆一下内联函数:

高阶函数:(为函数传入函数或者lambda表达式作为参数)

其调用过程:

  1. 程序将执行顺序转移到被调用函数或者lambda表达式所在的内存地址
  2. 当被调用的表达式或者函数执行完后,再回到原函数执行的地方

内联函数:使用inline关键字修饰带函数形参的函数即可;其实质就是讲被调用函数或者Lambda表达式函数体代码复制粘贴到调用函数中

内联属性要求:

  1. 该属性没有幕后字段

可以修饰属性的getter或者setter方法,或者修饰属性本身(表示同时修饰setter、getter方法)

和内联函数一样,在执行getter或者setter方法是会执行内联化

方法

Kotlin中方法和函数区别:

方法:指定定义在类中的函数
函数:

方法修饰符:public、protected、internal、private、final、abstract、open

函数修饰符:不能使用protected、abstract、final修饰

数据类

Kotlin提供的一种特殊的类,专门用于封装数据。

相关标签: Kotlin