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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Leslie_LN/article/details/82863016

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提供的一种特殊的类,专门用于封装数据。

猜你喜欢

转载自blog.csdn.net/Leslie_LN/article/details/82863016