知识点
作者:郑捡书
转载请注明作者和原文链接,如有行文存在不当请留言说明,谢谢!!
1. 关键字后加类名修饰一个类
2. 变量修饰符:表示可重新赋值,表示不可重新赋值(相当于java的final关键字)
3. 方法声明:关键字 方法名(方法参数){}
4. 假如一个类无类体,可以省略花括号‘{}’
5. 一个类可以有至多一个主构造函数,类名后添加关键字,再加构造参数。声明属性以及从主构造函数初始化属性,Kotlin 有简洁的语法,就是直接在主构函数的参数列表声明val或var修饰的属性
6.如果一个非抽象类没有声明构造函数(主构造函数或次构造函数),它会产生一个没有参数的构造函数。构造函数是 public 。如果你不想你的类有公共的构造函数,你就得声明一个私有的无参数列表主构造函数
7. 主构造函数如果没有任何注解或者可见性修饰符(,等),可以省略关键字
8. 一个类可以有无或者多个次构造函数
9. 如果存在显示主构造函数,则次构函数需要在参数后加表示间接调用主构函数。如果存在继承且在类名后无声明主构函数,则在类体中声明的构造函数要:super(父类构造方法的函数参数列表)
10. 主构函数的参数存在默认值(参数名:参数类型 = 默认参数值)则次构造函参数后面的this中的参数可以不传值
11. 类中的{}表示初始化代码块(相当于主构函数的方法体),主构函数的参数可以在此代码块出现。初始化块可以有多个,按照声明的顺序执行。初始化期间初始化块和属性初始化按照声明顺序执行(java的类初始化其实就是对字段的初始化)
12.{}代码块的内容先于次构函数的内容执行(因为{}代码块相当于主构函数的方法体,主构函数优于次构函数执行是因为次构函数都会调用主构函数)
13. 主构函数的参数可以赋值给成员属性(也就是说可以给属性使用)
14. var/val关键字修饰的属性
- 声明属性时同时赋值,也可以放在init()方法中,但as推荐直接赋值;
- 在var前添加关键字lateinit声明延迟初始化(val关键字不适用此定义)
- 该类声明为抽象类,该属性声明为抽象属性
- 放在主构函数的参数列表(创建对象的时候需要赋值),注意要有var或者val关键字,不然就表示参数。
- 可以提供get方法返回值(var关键字不适用此定义,因为var是可变的)
15. set和get可写也可不写, 不写的话会有默认的实现, 需要注意的是val修饰的变量是没有set方法的, 也不允许重写set方法。
16. get方法的默认格式为:get() = field,field 关键词只能用于属性的访问器,不能像java那么直接返回变量名,因为在kotlin的get中返回变量名相当于递归调用(kotlin中使用该变量名其实相当于调用了该变量的get方法)
17.在 JVM 虚拟机中,如果主构造函数的所有参数都有默认值,编译器会生成一个附加的无参的构造函数,这个构造函数会直接使用默认值,也就能使用无参构造函数来创建对象。(个人猜想jvm估计是帮我们创建了一个无参构造函数,然后使用主构函数的默认值调用主构函数,类似: constructor() : this(主构函数参数的默认值,这个参数可以是方法参数,也可以是val或者var修饰的属性) {} )
- 类实例化的时候每个属性必须要有初始值
- Nothing没有实例,是所有类型的子类。Any是所有类的父类(相当于java的Object类)
代码示例
// class关键字修饰一个类
class ClassDemo {
val s: String = ""
// 1.要么声明的时候赋初始值
// 2.要么可以放在init()中赋值,但as提示还是直接赋值
var i: Int = 1
// 方法
// 方法声明:fun关键字 方法名(方法参数){}
fun f() {
}
fun f2(s: String) {
}
}
// 无类体省略了花括号'{}',类体即java中的成员函数和成员变量,而在kotlin中成员变量也叫做属性
class ClassDemo2
// ‘constructor’关键字加构造参数表示主构造函数
// 方法参数表示‘(参数名 : 参数类型)’
class ClassDemo3 constructor(s: String) {
}
// 没有任何注解或者可见性修饰符可以省略关键字‘constructor’
class ClassDemo4(s: String) {
}
// 可见修饰符放在关键字‘constructor’前面
class ClassDemo5 private constructor(s: String) {
}
// 多个次构造函数(类似于java的方法重构)
class ClassDemo6 {
constructor(s: String)
constructor(i: Int)
constructor(s: String, i: Int)
}
class ClassDemo7 constructor(s: String) {
// 存在主构的话则次构函数在参数后‘: this(主构函数参数)’表示间接调用主构函数
constructor(i: Int, s: String) : this(s) {
}
}
// 主构函数参数存在默认值
class ClassDemo8 constructor(s: String = "默认值") {
// this()括号中可以不传值
constructor(i: Int, s: String) : this() {
}
}
class ClassDemo9 constructor(s: String) {
// 主构函数的参数可以赋值给属性
val n: String = s
var n1: String = s
// 初始化代码块(相当于主构函数的方法体)
// 主构函数的参数可以在此代码块中出现
init {
println("初始化代码块")
// (知识点)字符串模板 : $符号后面加上属性/变量
// 字符串模板相当于java中的打印信息引用变量的形式。即: println("调用主构函数的参数s:" + s)
println("调用主构函数的参数s:$s")
}
constructor(i: Int) : this("主构函数参数值") {
println("次构造函数")
}
}
class Demo13 {
var s: String = "哈哈"
var s1: String
lateinit var s2: String
val s3: String = ""
var s4: String = ""
get() = field.toUpperCase()
set(value) {
if (value == "哈哈") {
field = "大于"
} else {
field = "小于"
}
}
init {
s1 = "你好s2"
}
}
fun main(args: Array<String>) {
// 知识点
// kotlin创建对象:val/var修饰符 变量名 = 类名(主构或者次构参数值)。
// java创建对象: private/public修饰符 变量名 = new关键字 类名(构造函数参数值)。会java的同学一看就感觉和kotlin创建对象的方式其实很像
val classDemo9 = ClassDemo9(1)
}