kotlin
? * Kotlin 程序文件以 .kt 结尾
函数定义
? fun sum ( a : int , b : int ):int{
? return a+b
? }
? fun为函数定义关键字
? 表达式 fun sum(a: Int, b: Int) = a + b
? 无返回值 :unit
public类型必须有返回值类型,unit可以省略
变长参数 vararg v:Int
可变变量定义:var <标识符> : <类型> = <初始化值>
不可变变量定义:val <标识符> : <类型> = <初始化值>
声明时可以不指定类型,由编译器判断。
**.map:**将List中每个元素转换成新的元素,并添加到一个新的List中,最后将新List返回
字符串模板
$ 表示一个变量名或者变量值
$varName 表示变量值
${varName.fun()} 表示变量的方法返回值
null检查机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CNf0Nohu-1656659172755)(C:\Users\15629\Desktop\QQ截图20220401135308.png)]
区间表达式
? 具有操作符形式 … 的 rangeTo 函数辅以 in 和 !in 形成。 until 函数排除结束元素;4 downTo 1 。
Kotlin 基本数据类型
类型 | 位宽度 |
---|
double | 64 | float | 32 | long | 64 | int | 32 | short | 16 | byte | 8 |
- 十进制:123
- 长整型以大写的 L 结尾:123L
- 16 进制以 0x 开头:0x0F
- 2 进制以 0b 开头:0b00001011
- 注意:8进制不支持
- Doubles 默认写法:
123.5 , 123.5e10 - Floats 使用 f 或者 F 后缀:
123.5f
比较两个数字:三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小,每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针
类型转换:
toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double toChar(): Char
有些情况下也是可以使用自动类型转化的
Char 必需是单引号 ’ 包含起来的
特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、‘、"、\ 和 $。 编码其他字符要用 Unicode 转义序列语法:’\uFF00’。
Boolean 类型: || – 短路逻辑或、&& – 短路逻辑与、! - 逻辑非
数组:
? 创建两种方式:一种是使用函数arrayOf();
? ???另外一种是使用工厂函数。
字符串:String 是不可变的;三个引号 “”" 扩起来的字符串,支持多行字符串
String 可以通过 trimMargin() 方法来删除多余的空白。
字符串模板:
字符串可以包含模板表达式
以美元符($)开头;或者用花括号扩起来的任意表达式:
IF 表达式
一个 if 语句包含一个布尔表达式和一条或多条语句。
When 表达式
when 将它的参数和所有的分支条件顺序比较,直到某个分支满足条件。
else 同 switch 的 default。如果其他分支都不满足条件将会求值 else 分支。
可以检测一个值在(in)或者不在(!in)一个区间或者集合中
检测一个值是(is)或者不是(!is)一个特定类型的值
For 循环
for 循环可以对任何提供迭代器(iterator)的对象进行遍历,语法如下:
for (item in collection) print(item)
while 与 do…while 循环
while( 布尔表达式 ) { ? //循环内容 }
do { ? //代码语句 }while(布尔表达式);
返回和跳转
结构化跳转表达式:
- return。默认从最直接包围它的函数或者匿名函数返回。
- break。终止最直接包围它的循环。
- continue。继续下一次最直接包围它的循环。
标签的格式为标识符后跟 @ 符号
标签限制的 break 跳转到刚好位于该标签指定的循环后面的执行点。
continue 继续标签指定的循环的下一次迭代。
标签限制的 return 允许我们从外层函数返回。
扔物线
Kotlin 文件都是以 .kt 结尾的
变量声明:var v: View
空安全设计:不允许空。
? 可空类型:在类型右边加一个 ? 号,解除它的非空限制 ? var name: String? = null
? 断言式的调用「non-null asserted call」!!: ? view!!.setBackgroundColor(Color.RED)
延迟初始化: lateinit lateinit var view: View
类型推断:在声明的时候就赋值,可以不写变量类型var name*: String* = “Mike”
val 和 var:
数组的写法:var array: IntArray = intArrayOf(1, 2)
不装箱: ? 1.不可空类型。 ? 2.使用 IntArray、FloatArray 等
类和对象:
? 1.Kotlin 的类默认是 public 的。类默认是 final(使用 open )。
? 2.继承的写法,使用 : ,可以表示extends、implement
? class MainActivity : AppCompatActivity(), Impl {}
? 3.构造方法的写法不同。
? 4.override 的不同: 函数的可见性是继承自父类的。 ? 关闭 override 的遗传性:final override fun
? 5.abstract 关键字修饰的类无法直接实例化 ? 实例化一个对象更加简单: var activity: Activity = NewActivity()
类
class Runoob { // 类名为 Runoob ? // 大括号内是类体构成 }
成员函数: class Runoob() { ? fun foo() { print(“Foo”) } // 成员函数 }
主构造器
class Person constructor(firstName: String) { ? init { ? println(“FirstName is $firstName”) ? } }
不能包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用 init 关键字作为前缀
Kotlin 中类不能有字段。提供了 Backing Fields(后端变量) 机制,备用字段使用field关键字声明,field 关键词只能用于属性的访问器
一种可以延迟初始化的方案,使用 lateinit 关键字描述属性
二级构造函数,需要加前缀 constructor:
class Person { ? constructor(parent: Person) { ? parent.children.add(this) ? } } 如果类有主构造函数,每个次构造函数都要,或直接或间接通过另一个次构造函数代理主构造函数。在同一个类中代理另一个构造函数使用 this 关键字:
抽象类
抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。 注意:无需对抽象类或抽象成员标注open注解。
嵌套类
我们可以把类嵌套在其他类中。
内部类
内部类使用 inner 关键字来表示。 内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。
访问来自外部作用域的 this,我们使用this@label,其中 @label 是一个 代指 this 来源的标签。
匿名内部类
使用对象表达式来创建匿名内部类
类的修饰符
类的修饰符包括 classModifier 和_accessModifier_:
-
classModifier: 类属性修饰符,标示类本身特性。 ? abstract // 抽象类 ? final // 类不可继承,默认属性 ? enum // 枚举类 ? open // 类可继承,类默认是final的 ? annotation // 注解类 -
accessModifier: 访问权限修饰符 ? private // 仅在同一个文件中可见 ? protected // 同一个文件中或子类可见 ? public // 所有调用的地方都可见 ? internal // 同一个模块中可见
Kotlin 继承
? Kotlin 中所有类都继承该 Any 类
? Any 默认提供了三个函数:equals()、hashCode()、toString()
? 如果一个类要被继承,可以使用 open 关键字进行修饰。
构造函数
如果子类有主构造函数, 则基类必须在主构造函数中立即初始化。
如果子类没有主构造函数,则必须在每一个二级构造函数中用 super 关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法。
重写 override
在基类中,使用fun声明函数时,此函数默认为final修饰,不能被子类重写。如果允许子类重写该函数,那么就要手动添加 open 修饰它, 子类重写方法使用 override 关键词
如果有多个相同的方法(继承或者实现自其他类,如A、B类),则必须要重写该方法,使用super范型去选择性地调用父类的实现。super.f()//调用 A.f()
属性重写使用 override 关键字,属性必须具有兼容类型,每一个声明的属性都可以通过初始化程序或者getter方法被重写
可以用一个var属性重写一个val属性
Kotlin 接口
interface 接口中的属性只能是抽象的,不允许初始化值,接口不会保存属性值,实现接口时,必须重写属性
函数重写
实现多个接口时,可能会遇到同一方法继承多个实现的问题。
Kotlin 扩展
可以对一个类的属性和方法进行扩展
扩展函数
? 扩展函数定义形式: ? fun receiverType.functionName(params){ ? body ? }
? receiverType:表示函数的接收者,也就是函数扩展的对象 ? functionName:扩展函数的名称 ? params:扩展函数的参数,可以为NULL
? 扩展函数是静态解析的,并不是接收者类型的虚拟成员,在调用扩展函数时,具体被调用的的是哪一个函数,由调用函数的的对象表达式来决定的,而不是动态的类型决定的:
伴生对象的扩展
? 如果一个类定义有一个伴生对象 ,你也可以为伴生对象定义扩展函数和属性。伴生对象通过"类名."形式调用伴生对象,伴生对象声明的扩展函数,通过用类名限定符来调用。
扩展的作用域
扩展声明为成员
在一个类内部你可以为另一个类声明扩展。 在这个扩展中,有个多个隐含的接受者,其中扩展方法定义所在类的实例称为分发接受者,而扩展方法的目标类型的实例称为扩展接受者。
Kotlin 数据类与密封类
数据类
Kotlin 可以创建一个只包含数据的类,关键字为 data数据类需要满足以下条件: ? 主构造函数至少包含一个参数。 ? 所有的主构造函数的参数必须标识为val 或者 var ; ? 数据类不可以声明为 abstract , open , sealed 或者 inner ; ? 数据类不能继承其他类 (但是可以实现接口)。
复制
? 使用 copy() 函数,我们可以使用该函数复制对象并修改部分属性
数据类以及解构声明
? 组件函数允许数据类在解构声明中使用
标准数据类
? 标准库提供了 Pair 和 Triple 。在大多数情形中,命名数据类是更好的设计选择,因为这样代码可读性更强而且提供了有意义的名字和属性。
密封类
? 表示受限的类继承结构:当一个值为有限几种的类型, 而不能有任何其他类型时。在某种意义上,他们是枚举类的扩展:枚举类型的值集合 也是受限的,但每个枚举常量只存在一个实例,而密封类 的一个子类可以有可包含状态的多个实例。声明一个密封类,使用 sealed 修饰类,密封类可以有子类,但是所有的子类都必须要内嵌在密封类中。sealed 不能修饰 interface ,abstract class(会报 warning,但是不会出现编译错误)
Kotlin 泛型
“参数化类型”,将类型参数化,可以用在类,接口,方法上。
泛型约束
? 最常见的约束是上界(upper bound):
型变
? 没有通配符类型,它有两个其他的东西:声明处型变(declaration-site variance)与类型投影(type projections)
声明处型变
? 声明处的类型变异使用协变注解修饰符:in、out,消费者 in, 生产者 out。
? 使用 out 使得一个类型参数协变,协变类型参数只能用作输出,可以作为返回值类型但是无法作为入参的类型:
星号投射
Kotlin 枚举类
枚举初始化
使用枚举常量
Kotlin 对象表达式和对象声明
对象表达式
对象声明
伴生对象
对象表达式和对象声明之间的语义差异
函数定义 如果不改变返回值使用also或apply
如果是设置属性值使用apply或run,作为参数运算使用also或let
with基本可以不用
|