Kotlin基础学习记录
1.类和对象
定义
空类:
class User
主构造器:
class User constructor(firstName:String){
//若主构造器没有任何注解或修饰符,可省略constructor关键字
//若未定义任何构造器,系统提供public修饰的无参构造器
}
创建对象:(不需要使用new关键字)
var user:User
user = User("user")
// or
var user1 = User("user1")
对象的this引用
指向调用该方法的对象
两种情形:
- 在构造器中引用该构造器正在初始化的对象
- 在方法中引用调用该方法的对象
作用:
- 类中的一个方法访问该类的另一个方法或属性 (可省略this前缀)
- 若方法中有一个局部变量与属性同名,使用this访问属性
var foo:Int = 0
fun test(){
var foo: Int
foo = 6
this.foo = 5
print(foo)
print(this.foo)
}
//output:65
- 可以像访问普通变量一样访问this引用,甚至可以作为方法的返回值
class ReturnThis {
var age = 0
fun grow():ReturnThis{
age++
return this
}
}
fun testReturnThis() {
val rt = ReturnThis()
//连续调用同一个方法
//可能造成实际意义的模糊
rt.grow().grow().grow()
print(rt.age)
}
2.方法详解
方法与函数
方法定义在类中
中缀表示法
infix修饰,只能有一个参数
类似于双目运算
componentN方法与解构
批量赋值???
类中定义componentN方法,operator修饰
operator fun component1(): Int {
return this.a
}
operator fun component2(): Int {
return this.b
}
使用:
var (a,b) = user
数据类和返回多个值的函数
返回多个值——>返回一个支持解构的对象
数据类——>专门用于封装数据,自动生成componentN方法
在lambda表达式中解构
参数支持解构 括号中多个参数
3.属性和字段
读写属性、只读属性
读写属性:var 有getter和setter方法
只读属性:val 只有getter方法
自定义getter、setter方法
无须使用fun关键字
val str:String
get() {
print("getter")
return s
}
仅改变可见性或添加注解:
var n:String
get() {return s}
private set(value) {}
var t:String
get() {return s}
@Inject set(value) {}
幕后字段
kotlin中定义一个普通属性时,会生成一个field(字段)、getter和setter方法(只读属性没有setter)。field称为幕后字段。
属性有幕后字段,则需要显式指定初始值;反之,则不允许指定初始值。
何时生产幕后字段:
- 属性使用其getter和setter方法或其中之一
- 重写getter、setter方法
重写getter、setter方法中不能使用点语法对属性赋值(点语法赋值本质是调用getter、setter方法)
幕后属性
private修饰的属性
开发者必须为幕后属性提供getter、setter方法
延迟初始化属性
lateinit修饰符
kotlin不会为属性执行默认初始化
内联属性
inline修饰符
可修饰getter方法、setter方法、属性本身
4.隐藏和封装
包和导包
与Java类似
import语句支持as(python) import A as B
访问控制符
private、internal、protected、public(默认)
– | java | kotlin |
---|---|---|
访问权限 | – | 取消了default;新增internal;取消了protected的包访问权限 |
默认访问权限 | default | public |
5.构造器
主构造器和初始化块
主构造器形参的作用:
- 初始化块可以使用
- 声明属性时可以使用
初始化块的语法格式:
init{
//可执行代码
}
kotlin中,主构造器属于初始化块,或者说初始化块是主构造器的执行体
次构造器和构造器重载
次构造器必须委托调用主构造器(执行初始化块)
可将多个构造器中相同的代码抽取到初始化块中,提高复用性
class Test(name : String) {
var mName : String
init {
mName = name
}
//委托给主构造器
//委托给哪个构造器取决于传入的参数
constructor(name : String, age :Int) : this(name){
}
}
主构造器声明属性
直接在参数之前使用var或val声明
6.继承
单继承
语法格式:
修饰符 class SubClass : SuperClass {
//类定义部分
//类默认为final,所以SuperClass需要声明为open
}
子类的构造器也需要委托调用父类构造器
重写父类方法、属性
override修饰
被重写的方法需要为open
两同两小一大原则
super
调用父类的属性或方法
强制重写
子类从多个直接超类型(接口或类)继承了同名成员,则必须重写该成员
open class A {
open fun test() {
print("A的test")
}
}
interface B {
fun test() {
print("B的test")
}
}
class C() : A(), B {
override fun test() {
super<A>.test()
super<B>.test()
}
}
7.多态
多态性
相同类型的变量,调用同一个方法时呈现出多种不同子类的行为特征
只能调用编译时类型的成员
is检查类型
为了令变量可以调用运行时类型的成员,需要把它强制转换成运行时类型
强制转型运算符:as 和 as?
为保证类型转换不出错,kotlin提供类型检查运算符 is 和 is
is 前面的操作数的编译时类型要么与 is 后面的类型相同,要么具有继承关系,否则编译程序时报错
只要使用了 is 或 !is ,系统就会自动将变量的类型转换为目标类型
as运算符转型
只能在具有继承关系的两种类型之间进行
向下转型:运行时类型和目标类型一致