Kotlin 学习笔记
Kotlin 基本数据类型
数值类型
- Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double 等.
- 比较两个数字 .
三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小。
fun main(args: Array<String>) {
val a: Int = 10000
println(a === a) // true,值相等,对象地址相等
//经过了装箱,创建了两个不同的对象
val boxedA: Int? = a
val anotherBoxedA: Int? = a
//虽然经过了装箱,但是值是相等的,都是10000
println(boxedA === anotherBoxedA) // false,值相等,对象地址不一样
println(boxedA == anotherBoxedA) // true,值相等
}
- 类型转换
每种数据类型都有下面的这些方法,可以转化为其它的类型:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
val l = 1L + 3 // Long + Int => Long // 自动转换为较大的类型 和 Java C一样
字符
- Kotlin 中的 Char 不能直接和数字操作,Char 必需是单引号 ’ 包含起来的。比如普通字符 ‘0’,‘a’。
布尔
|| – 短路逻辑或
&& – 短路逻辑与
! - 逻辑非
数组
数组的创建两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数
fun main(args: Array<String>) {
//[1,2,3]
val a = arrayOf(1, 2, 3)
//[0,2,4]
val b = Array(3, { i -> (i * 2) })
//读取数组内容
println(a[0]) // 输出结果:1
println(b[1]) // 输出结果:2
}
字符串
- String 可以通过 trimMargin() 方法来删除多余的空白。
fun main(args: Array<String>) {
val text = """
|多行字符串
|菜鸟教程
|多行字符串
|Runoob
""".trimMargin()
println(text) // 前置空格删除了
}
- 字符串模板
val s = "i = $i" // 求值结果为 "i = 10"
val str = "$s.length is ${s.length}" // 求值结果为 "runoob.length is 6"
Kotlin 条件控制
IF 表达式
When 表达式
when 类似其他语言的 switch 操作符。其最简单的形式如下:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x 不是 1 ,也不是 2")
}
}
Kotlin 循环控制
For 循环
- for 循环可以对任何提供迭代器(iterator)的对象进行遍历,语法如下:
for (item in collection) print(item)
- 如果想要通过索引遍历一个数组或者一个 list,可以这么做:
for (i in array.indices) {
print(array[i])
}
- 可以用库函数 withIndex:
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
while 与 do…while 循环
返回和跳转
- return。默认从最直接包围它的函数或者匿名函数返回。
- break。终止最直接包围它的循环。
- continue。继续下一次最直接包围它的循环。
Kotlin 类和对象
类定义
Kotlin 类可以包含:构造函数和初始化代码块、函数、属性、内部类、对象声明。
class Runoob() {
fun foo() {
print("Foo")
} // 成员函数
}
类的属性
var allByDefault: Int? // 错误: 需要一个初始化语句, 默认实现了 getter 和 setter 方法
var initialized = 1 // 类型为 Int, 默认实现了 getter 和 setter
val simple: Int? // 类型为 Int ,默认实现 getter ,但必须在构造函数中初始化
val inferredType = 1 // 类型为 Int 类型,默认实现 getter
主构造器
因为主构造函数不能有代码 所以有一个init的初始化方法 来完成初始化时的一些操作
class Person constructor(firstName: String) {
init {
println("FirstName is $firstName")
}
}
次构造函数
类也可以有二级构造函数,需要加前缀 constructor:
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
如果类有主构造函数,每个次构造函数都要,或直接或间接通过另一个次构造函数代理主构造函数
class Person(val name: String) {
constructor (name: String, age:Int) : this(name) {
// 初始化...
}
}
抽象类
abstract class Derived : Base() {
override abstract fun f()
}
嵌套类
class Outer { // 外部类
private val bar: Int = 1
class Nested { // 嵌套类
fun foo() = 2
}
}
fun main(args: Array<String>) {
val demo = Outer.Nested().foo() // 调用格式:外部类.嵌套类.嵌套类方法/属性
println(demo) // == 2
}
内部类
内部类使用 inner 关键字来表示。
内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。
class Outer {
private val bar: Int = 1
var v = "成员属性"
/**嵌套内部类**/
inner class Inner {
fun foo() = bar // 访问外部类成员
fun innerTest() {
var o = this@Outer //获取外部类的成员变量
println("内部类可以引用外部类的成员,例如:" + o.v)
}
}
}
fun main(args: Array<String>) {
val demo = Outer().Inner().foo()
println(demo) // 1
val demo2 = Outer().Inner().innerTest()
println(demo2) // 内部类可以引用外部类的成员,例如:成员属性
}
类的修饰符
- 类属性修饰符,标示类本身特性。
abstract // 抽象类
final // 类不可继承,默认属性
enum // 枚举类
open // 类可继承,类默认是final的
annotation // 注解类
- 访问权限修饰符
private // 仅在同一个文件中可见
protected // 同一个文件中或子类可见
public // 所有调用的地方都可见
internal // 同一个模块中可见
Kotlin 继承
如果一个类要被继承,可以使用 open 关键字进行修饰。
open class Base(p: Int) // 定义基类
class Derived(p: Int) : Base(p)
构造函数
子类有主构造函数
如果子类有主构造函数, 则基类必须在主构造函数中立即初始化。
open class Person(var name : String, var age : Int){// 基类
}
class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {
}
子类没有主构造函数
如果子类没有主构造函数,则必须在每一个二级构造函数中用 super 关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法。
/**用户基类**/
open class Person(name:String){
/**次级构造函数**/
constructor(name:String,age:Int):this(name){
//初始化
println("-------基类次级构造函数---------")
}
}
/**子类继承 Person 类**/
class Student:Person{
/**次级构造函数**/
constructor(name:String,age:Int,no:String,score:Int):super(name,age){
println("-------继承类次级构造函数---------")
println("学生名: ${name}")
println("年龄: ${age}")
println("学生号: ${no}")
println("成绩: ${score}")
}
}
fun main(args: Array<String>) {
var s = Student("Runoob", 18, "S12345", 89)
}
重写
在基类中,使用fun声明函数时,此函数默认为final修饰,不能被子类重写。如果允许子类重写该函数,那么就要手动添加 open 修饰它, 子类重写方法使用 override 关键词:
/**用户基类**/
open class Person{
open fun study(){ // 允许子类重写
println("我毕业了")
}
}
/**子类继承 Person 类**/
class Student : Person() {
override fun study(){ // 重写方法
println("我在读大学")
}
}
fun main(args: Array<String>) {
val s = Student()
s.study();
}