类:
声明类的关键字--class(和Java一样)
类由三部分组成:
第一部分:类名
第二部分:类头,类头包含主构造函数和类型参数,类头可选(即可有可无)
第三部分:类体,类体被包含在花括号内,如果没有类体,可以省略花括号,类体可选(即可有可无)
如:class BaseAdapter constructor(name : String) {/****/}
(BaseAdapter为类名,constructor为构造函数关键字,name为构造函数参数,String为构造函数参数类型,花括号内部为类体)。如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字,即class BaseAdapter(name : String){/****/}
主构造函数:
主构造函数不包含任何代码,一个类只有一个主构造函数。没有声明主构造函数时,会生成一个默认的不带参数的主构造函数。如果主构成函数的所有参数都有默认值,编译器会生成一个无参构造函数,它将使用默认值。
没有声明主构造函数的类:class Fruit {/****/}
不带参数的主构造函数类:class Fruit() {/****/}
带参数的主构造函数类:class Fruit(name : String) {/****/}
主构造函数参数有默认值:class Fruit(name : String = "MyName") {/****/}
次构造函数:
(1)前缀:无论是否存在主构造函数,类中都可以声明前缀为constructor(非关键字)的次构造函数。
(2)委托:次构造函数需要使用this关键字通过自己直接委托或其他构造函数间接委托给主构造函数,即使该类没有主构造函数,这种委托也会隐式发生(即不需要跟“this()”)。子类的次构造函数可以间接委托给基类对应的次构造函数,基类的次构造函数直接委托给基类的主构造函数
如:次构造函数constructor(name : String, id : String) : this(name) {/****/}
类成员:
构造函数与初始化块、属性、函数、嵌套类与内部类、对象声明
属性:
属性组成部分:var 属性名 : 属性类型 = 初始器
val只读属性:有getter(即get()方法), 没有setter(即set()方法),如果不想在声明的时候立即初始化val属性,可以允许它先为null,后续调用的时候需在属性后添加!!
或?
进行空处理
var可变属性:有getter和setter,如果不想在声明的时候立即初始化var属性,可以添加lateinit修饰符标记该属性,需要的时候再初始化,可以通过.isInitialized
判断是否已初始化
private lateinit var mSoundPool : SoundPool
private val mSoundList : SparseIntArray? = null
...
mSoundList?.put(1,1)// ?表示mSoundList不为空时执行,为空时添加要返回的信息(mSoundList?.put(1,1) ?: null),因为put返回的是void,所以这里可以忽略?:null
mSoundList!!.put(2,2)// !!表示不为空时执行,为空时会抛异常
mSoundList.put(3,3)// 如果前面的代码已添加过!!,后面则不需要再添加
自定义访问器getter: val name : String get() = "name"
。如果我们定义了一个自定义的 getter,那么每次访问该属性时都会调用它。自 Kotlin 1.1 起,如果可以从 getter 推断出属性类型,则可以省略它:val name : get() = "name"
自定义访问器setter:
var name : String get() = this.toString() // 注意这里要换行
set(value) {/****/}
如果我们定义了一个自定义的 setter,那么每次给属性赋值时都会调用它
属性延迟初始化:属性前添加“lateinit”修饰符,不能是主构造函数中的属性,不能是原生类型,不能自定义getter和setter
幕后字段:
幕后字段通过field标识符在属性的访问器中引用,field只能用在属性的访问器内。
属性生成幕后字段的条件有两个,满足其中一个便会生成幕后字段。
1.(getter和setter两个访问器中,如果是val属性则只有getter访问器)至少有一个访问器是默认访问器(即不是自定义访问器),就会为该属性生成一个幕后字段。
2.在自定义访问器中通过field标识符引用了幕后字段。