Kotlin学习笔记1

数组

/**
 * 何时使用数组
 */
fun useDemo() {
    // Kotlin 中最常见的数组类型是对象类型数组,由 Array 类表示。
    // 如果在对象类型数组中使用原生类型,那么会对性能产生影响,因为原生值都装箱成了对象。 为了避免装箱开销,请改用原生类型数组。
    var strArray = arrayOf("At", "Brod", "Cak")
    // 使用 += 赋值操作创建了一个新的 riversArray,复制了原始元素并添加新元素
    strArray += "Dart"
    println(strArray.joinToString("-"))
}

/**
 * 创建数组
 * arrayOf()  arrayOfNulls()  emptyArray() and Array constructor.
 */
fun arrayDemo() {
    val arr1 = arrayOf(1, 2, 3, 4, 5, 6)
    println(arr1.joinToString())

    val nullArray: Array<Int?> = arrayOfNulls(3)
    println(nullArray.joinToString())

    var exampleArray = emptyArray<String>()
    var exampleArray2: Array<String> = emptyArray()
}

fun arrayDemo2() {
    // Creates a two-dimensional array
    val twoDArray = Array(2) { Array<Int>(2) { 0 } }
    println(twoDArray.contentDeepToString())
    // [[0, 0], [0, 0]]

    // Creates a three-dimensional array
    val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } }
    println(threeDArray.contentDeepToString())
}

/**
 * 访问与修改元素
 */
fun operatorDemo() {
    val intArray = arrayOf(1, 2, 3)
    intArray[0] = 10
    println(intArray.joinToString())
}

fun printAllStrings(vararg strings: String) {
    for (string in strings) {
        print(string)
    }
}

fun varargDemo() {
    val lettersArray = arrayOf("c", "d")
    printAllStrings("a", "b", *lettersArray)
    println()
}

/**
 * 将数组转换为集合
 */

fun toListDemo() {
    val simpleArray = arrayOf("a", "b", "c", "c")
    println(simpleArray.toSet())
    println(simpleArray.toList())

    val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)
    println(pairArray.joinToString())
    println(pairArray.toMap())

}

/**
 * BooleanArray	boolean[]
 * ByteArray	byte[]
 * CharArray	char[]
 * DoubleArray	double[]
 * FloatArray	float[]
 * IntArray	    int[]
 * LongArray	long[]
 * ShortArray	short[]
 */
fun arrayDemo3() {
    val exampleArray = IntArray(5)
    println(exampleArray.joinToString())
}

fun main() {
//    useDemo()
//    arrayDemo()
    arrayDemo2()
    operatorDemo()
    varargDemo()
    toListDemo()
}

类型检测和类型转换

package com.mcc.myapplication

fun getNum(): Number {
    return 100F
}

/**
 * is 与 !is 操作符
 */
fun isDemo() {
    val obj = "hello"
    if (obj is String) {
        println("string length:${obj.length}")
    }
    val value = 1
    if (value is Int) {
        println("$value is Int")
    }
    val num = getNum()
    if (num !is Int) {
        println("$num not is Int")
    }
}

/**
 *  智能转换
 */
fun transferDemo(x: Any) {
    if (x is String) {

        println("this param is string, and length:${x.length}") // x 自动转换为字符串
    }
}

fun transferDemo2(x: Any) {
    if (x !is String) return
    // 如果反向检测导致返回那么该转换是安全的
    println("this param is string, and length:${x.length}")
}

fun transferDemo3(x: Any) {
    // `||` 右侧的 x 自动转换为 String
    if (x !is String || x.length == 0) return

    // `&&` 右侧的 x 自动转换为 String
    if (x is String && x.length > 0) {
        println("this param is string, and length:${x.length}")
    }
}

fun transferDemo4(x: Any) {
    when (x) {
        is Int -> print(x + 1)
        is String -> print(x.length + 1)
        is IntArray -> print(x.sum())
    }
}

fun transferDemo5(x: Any) {
    // “不安全的”转换操作符
    val y: String? = x as String?
    if (y != null) {
        println("this param is string, and length:${x.length}")
    }
}

fun transferDemo6(x: Any) {
    // “安全的”(可空)转换操作符
    val y: String? = x as? String
    if (y != null) {
        println("this param is string, and length:${x.length}")
    }
}

fun main() {
    isDemo()
    transferDemo("world")
    transferDemo2("gogogo")
    transferDemo3("pythonX")
    transferDemo4(intArrayOf(1, 2, 3, 4, 5))
    transferDemo4(arrayOf(1, 2, 3, 4, 5, 6))
//    transferDemo5(111)
    transferDemo6(111)
}

If 表达式


fun main() {
    val a = 2
    val b = 3
    var max: Int? = null
    if (a > b) {
        max = a
    } else {
        max = b
    }
    // 作为表达式
    max = if (a > b) a else b
    println("max is $max")

    val c = 10
    val maxOrLimit = if (c > a) c else if (a > b) a else b
    println("maxOrLimit is $maxOrLimit")

    // if 表达式的分支可以是代码块,这种情况最后的表达式作为该块的值
    val max2 = if (a > b) {
        print("Choose a,")
        a
    } else {
        print("Choose b,")
        b
    }
    println("max2 is $max2")
}

When 表达式

fun whenDemo1(x: Int) {
    when (x) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> {
            print("x=$x is neither 1 nor 2")
        }
    }
    println()
}

enum class Bit {
    ZERO, ONE, TWO
}

fun getRandomBit(): Bit {
    return Bit.ZERO
}

fun whenDemo2() {
    val numericValue = when (getRandomBit()) {
        Bit.ZERO -> 0
        Bit.ONE -> 1
        Bit.TWO -> 2
        // 'else' is not required because all cases are covered
    }
    println(numericValue)
}

fun whenDemo3(x: Int, s: String) {
    when (x) {
        0, 1 -> print("x == 0 or x == 1")
        else -> print("otherwise")
    }

    when (x) {
        s.toInt() -> print("s encodes x")
        else -> print("s does not encode x")
    }

    val validNumbers = listOf(3, 4, 5)
    when (x) {
        in 1..10 -> print("x is in the range")
        in validNumbers -> print("x is valid")
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
}

fun main() {
    whenDemo1(3)
    whenDemo2()
}

For 循环

fun main() {
    // for 循环可以对任何提供迭代器(iterator)的对象进行遍历
    val ints = listOf(2, 3, 4, 5, 6)
    for (item: Int in ints) {
        print(item)
    }
    println()

    for (i in 1..3) {
        print(i)
    }
    println()
    for (i in 6 downTo 0 step 2) {
        print(i)
    }
    println()

    val array = arrayOf("a", "b", "c")
    for (i in array.indices) {
        print(array[i])
    }
    println()
    for ((index, value) in array.withIndex()) {
        println("the element at $index is $value")
    }
}

while 循环

while (x > 0) {
    x--
}

do {
  val y = retrieveData()
} while (y != null) // y 在此处可见

返回与跳转


/**
 * 在 Kotlin 中任何表达式都可以用标签来标记。 标签的格式为标识符后跟 @ 符号
 */
fun demo1() {
    loop@ for (i in 1..100) {
        for (j in 1..100) {
            if (j > 1) break@loop
            println(j)
        }
    }
}

/**
 * 返回到标签
 */
fun demo2() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return // 非局部直接返回到 demo2() 的调用者
        print(it)
    }
    println("this point is unreachable")
}

fun demo3() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者——forEach 循环
        print(it)
    }
    print(" done with explicit label")
}

fun demo4() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者——forEach 循环
        print(it)
    }
    print(" done with implicit label")
}

fun demo5() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // 局部返回到匿名函数的调用者——forEach 循环
        print(value)
    })
    print(" done with anonymous function")
}

fun main() {
    demo5()
}

异常

/**
 * try {
 *     // 一些代码
 * } catch (e: SomeException) {
 *     // 处理程序
 * } finally {
 *     // 可选的 finally 块
 * }
 */

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

fun main(){
    val input = "2"
    val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }
}

包与导入

package com.mcc.myapplication

fun printMessage() { /*……*/
}

class Message { /*……*/ }

/**
 * 源文件所有内容(无论是类还是函数)都包含在该包内。
 * 所以上例中 printMessage() 的全名是 org.example.printMessage,
 * 而 Message 的全名是 org.example.Message
 */

/**
 * 默认导入
 * 有多个包会默认导入到每个 Kotlin 文件中:
 * kotlin.*
 * kotlin.annotation.*
 * kotlin.collections.*
 * kotlin.comparisons.*
 * kotlin.io.*
 * kotlin.ranges.*
 * kotlin.sequences.*
 * kotlin.text.*
 *
 * JVM:
 * java.lang.*
 * kotlin.jvm.*
 *
 * 如果出现名字冲突,可以使用 as 关键字在本地重命名冲突项来消歧义:
 * import org.example.Message // Message 可访问
 * import org.test.Message as TestMessage // TestMessage 代表“org.test.Message”
 *
 * 关键字 import 并不仅限于导入类;也可用它来导入其他声明:
 * 顶层函数及属性
 * 在对象声明中声明的函数和属性
 * 枚举常量
 */

fun main() {

}

类与构造函数

package com.mcc.myapplication

import javax.inject.Inject

class Person { /*……*/ }

class Empty

class Student constructor(firstName: String) { /*……*/ }
// 如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字
// class Student(firstName: String) { /*……*/ }

class Customer public @Inject constructor(name: String) { /*……*/ }
// 如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints $name")
    }

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

class Person2(val firstName: String, val lastName: String, var age: Int)

class Person3(val firstName: String, val lastName: String, var isEmployed: Boolean = true)

// 次构造函数
class Person4(val pets: MutableList<Pet> = mutableListOf())

class Pet {
    constructor(owner: Person4) {
        owner.pets.add(this) // adds this pet to the list of its owner's pets
    }
}

class Person5(val name: String) {
    val children: MutableList<Person5> = mutableListOf()

    // 如果类有一个主构造函数,每个次构造函数需要委托给主构造函数,
    // 可以直接委托或者通过别的次构造函数间接委托
    // 委托到同一个类的另一个构造函数用 this 关键字即可
    constructor(name: String, parent: Person5) : this(name) {
        parent.children.add(this)
    }
}

class Constructors {
    init {
        println("Init block")
    }

    constructor(i: Int) {
        println("Constructor i=$i")
    }

    constructor(i: Int, ss: String) : this(i) {
        println("Constructor ss=$ss")
    }

}

// 如果一个非抽象类没有声明任何(主或次)构造函数,它会有一个生成的不带参数的主构造函数。构造函数的可见性是 public。
class DoCreateMe private constructor() { /*……*/ }

// 如果你不希望你的类有一个公有构造函数,那么声明一个带有非默认可见性的空的主构造函数
class DonotCreateMe private constructor() { /*……*/ }

// 如果主构造函数的所有的参数都有默认值,编译器会生成一个额外的无参构造函数
class Customer2(val name: String = "", val age: Int = 18)

fun main() {
    val p = Person()
    val e = Empty()
    val s = Student("SnZ")
    InitOrderDemo("YourName")
    Person2("morning", "cat", 30)
    Person3("morning", "cat")
    val p4 = Person4()
    Pet(p4)
    Pet(p4)
    p4.pets.toList().joinToString().also(::println)
    val p5 = Person5("ZhangSan")
    Person5("ZhangXiao", p5)
    Constructors(33, "mcc")
    Customer2()
}

抽象类

// 类以及其中的某些或全部成员可以声明为 abstract
abstract class Polygon {
    abstract fun draw()
}

class Rectangle : Polygon() {
    override fun draw() {
        // draw the rectangle
    }
}

// 可以用一个抽象成员覆盖一个非抽象的开放成员
open class Polygon2 {
    open fun draw() {
        // some default polygon drawing method
    }
}

abstract class WildShape : Polygon2() {
    // Classes that inherit WildShape need to provide their own
    // draw method instead of using the default on Polygon
    abstract override fun draw()
}

类的继承

package com.mcc.myapplication

// 在 Kotlin 中所有类都有一个共同的超类 Any,对于没有超类型声明的类它是默认超类
class Example : Any() // 从 Any 隐式继承

// 默认情况下,Kotlin 类是最终(final)的——它们不能被继承。 要使一个类可继承,请用 open 关键字
open class Base(p: Int) // 该类开放继承

class Derived(p: Int) : Base(p)

// 如果派生类没有主构造函数,那么每个次构造函数必须使用super 关键字初始化其基类型
class MyClass : Base {
    constructor(ctx: Int) : super(ctx)

    constructor(ctx: Int, name: String) : super(ctx)
}

// Kotlin 对于可覆盖的成员以及覆盖后的成员需要显式修饰符
open class Shape {
    open val vertexCount: Int = 0

    open fun draw() { /*……*/
    }

    // 如果函数没有标注 open 如 Shape.fill(),那么子类中不允许定义相同签名的函数
    fun fill() { /*……*/
    }
}

class Circle() : Shape() {
    override fun draw() { /*……*/
    }
}

// 将 open 修饰符添加到 final 类(即没有 open 的类) 的成员上不起作用

// 标记为 override 的成员本身是开放的,因此可以在子类中覆盖。如果你想禁止再次覆盖, 使用 final 关键字
open class Rectangle() : Shape() {

    // 属性与方法的覆盖机制相同。在超类中声明然后在派生类中重新声明的属性必须以 override 开头,并且它们必须具有兼容的类型。
    override val vertexCount = 4

    final override fun draw() { /*……*/
    }
}

interface Shape2 {
    val vertexCount: Int
}

class Rectangle2(override val vertexCount: Int = 4) : Shape2 // 总是有 4 个顶点

class Polygon2 : Shape2 {
    override var vertexCount: Int = 0  // 以后可以设置为任何数
}

// 派生类初始化顺序


// 调用超类实现


// 覆盖规则

fun main() {

}

类的属性


  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值