kotlin语言学习记录(更新)

Kotlin 基本语法

资料

https://book.kotlincn.net/text/basic-syntax.html
https://kotlinlang.org/docs/inheritance.html#overriding-rules

代码

https://gitee.com/hellosunshine/kotlin_study.git

输出
fun main(args: Array<String>) {
    println(args.contentToString())
    print("Hello")
}
函数
fun main() {
    print("sum of 3 and 5 is")
    println(sum01(3, 5))
    println(sum(3, 5))
    printSum(-1, 8)
    
}
fun sum01(a: Int, b: Int): Int {
    return a + b
}
fun sum(a: Int, b: Int) = a + b
fun printSum(a: Int, b: Int) {
    println("sum of $a and $b is ${a + b}")
}
变量
var x = 0
fun main() {
    val a: Int = 1
    val b = 2
    val c: Int
    c = 3
    println("a = $a, b = $b, c = $c")

//    var x = 5
//    x += 1
//    println("x = $x")

    val PI = 3.14
    println("x = $x; PI = $PI")
    incrementX()
    println("incrementX()")
    println("x = $x; PI = $PI")
}

fun incrementX() {
    x += 1
}
类与实例
  • 普通类
class Shape

class Rectangle(var height: Double, var length: Double) {
    var perimeter = (height + length) * 2
}
fun main() {
    val rectangle = Rectangle(5.0, 2.0)
    println("The perimeter is ${rectangle.perimeter}")
}
  • 继承类 定义为 open class
//open为继承
open class Shape
class Rectangle(var height: Double, var length: Double) : Shape() {
    var perimeter = (height + length) * 2
}
if表达式
fun main() {
    println("max of 0 and 42 is ${maxOf(0, 1)}")
}
fun maxOf(a: Int, b: Int) = if (a > b) a else b
for,while循环
fun main() {
    val items = listOf("apple", "banana", "kiwifruit")
    for (item in items) {
        println(item)
    }
    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
    var index = 0
    while (index < items.size) {
        println("item at $index is ${items[index]}")
        index++
    }
}
when表达式
fun describe(obj: Any): String =
    when (obj) {
        1 -> "One"
        "Hello" -> "Greeting"
        is Long -> "Long"
        !is String -> "Not a string"
        else -> "Unknown"
    }
fun main() {
    println(describe(1))
    println(describe("Hello"))
    println(describe(1000L))
    println(describe(2))
    println(describe("other"))
}
range(区间)
    val x = 10
    val y = 9
    //in监测数字是否在执行区域内
    if(x in 1..y+1) {
        println("fits in range")
    }
	//!in监测数据不在范围内
    val list = listOf("a", "b", "c")
    if(-1 !in 0..list.lastIndex) {
        println("-1 is out of range")
    }
    if(list.size !in list.indices) {
        println("list size is out of valid list indices range, too")
    }
数列迭代
for (x in 1..5) {
        print(x)
    }
    println()
    for (x in 1..10 step 2) {
        print(x)
    }
    println()
    for (x in 9 downTo 0 step 3) {
        print(x)
    }
集合
fun main() {
    //集合迭代
    val items = listOf("apple", "banana", "kiwifruit")
    for (item in items) {
        println(item)
    }
    //in判断是否在集合内
    when {
        "orange" in items -> println("juicy")
        "apple" in items -> println("apple is fine too")
    }
    //过滤排序映射
    val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
    fruits.filter { it.startsWith("a") }
        .map { it.uppercase() }
        .sortedBy { it }
        .forEach { println(it) }
}
空值检测
fun printProduct(arg1: String, arg2:String) {
    val x = parseInt(arg1)
    val y = parseInt(arg2)
    if(x != null && y != null) {
        println(x * y)
    } else {
        println("'$arg1' or '$arg2' is not a number")
    }
//    if(x == null) {
//        println("Wrong number format in arg1: '$arg1'");
//    }
//    if(y == null) {
//        println("Wrong number format in arg2: '$arg2'");
//    }
}

fun main() {
    printProduct("6", "7")
    printProduct("a", "7")
    printProduct("a", "b")
}
类型检测与自动类型转换
fun getStringLength(obj: Any): Int? {
//    if (obj is String) {
//        return obj.length
//    }
//    return null;

    if(obj !is String) {
        return null;
    }
    //obj自动转换为String
    return obj.length;

//    if (obj is String && obj.length > 0) {
//        return obj.length
//    }
//    return null;
}

fun main() {
    fun printLength(obj: Any) {
        println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"}")
    }
    printLength("Incomprehensibility")
    printLength(1000)
    printLength(listOf(Any()))
}

kotlin习惯用法

package com.example.kotlinstudy.customUsage

import android.os.Build
import androidx.constraintlayout.solver.widgets.Rectangle
import java.io.File
import java.lang.ArithmeticException
import java.lang.IllegalArgumentException
import java.lang.IllegalStateException
import java.math.BigDecimal
import java.nio.file.Files
import java.nio.file.Paths

//创建DTO
data class Customer(val name: String, val email: String)

//函数的默认参数
fun foo(a: Int = 0, b: String = "") {}

//过滤list
val list = listOf<Int>(0, 2, 3);
val positives = list.filter { x -> x > 0 }
val positives02 = list.filter { it > 0 }
fun main() {
    for (item in positives) {
        print(item)
    }
    println()
    for (item in positives02) {
        print(item)
    }
    println()
    val emailsList = listOf<String>("john@example.com", "john@example.com");
    //检察元素是否存在于集合中
    if ("john@example.com" in emailsList) {
        println("存在")
    }
    //字符串内插
    val name = "name"
    println("Name $name")
    //类型判断
    val tempList = listOf<Any>(0, "2", 3.1);
    for (obj in tempList) {
        when (obj) {
            is Int -> {
                println("$obj is Int")
            }
            is String -> {
                println("$obj is String")
            }
            else -> {
                println("$obj is Any")
            }
        }
    }
    //只读list
    val list = listOf<String>("a", "b", "c")
    //访问map条目
    val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
    println(map["a"])
    map["a"] = 2
    println(map["a"])
    //遍历map或者pair型list
    for ((k, v) in map) {
        println("$k -> $v")
    }
    ///区间迭代
    for (i in 1..10) {
        print(i)
    }
    println()
    for (x in 2..10 step 2) {
        print(x)
    }
    println()
    for (x in 10 downTo 1) {
        print(x)
    }
    println()
    (1..10).forEach { a ->
        print(a)
    }
    //延迟属性
//    val p: String by lazy {}
    //扩展函数
    fun String.spaceToCamelCase() {}
    "Convert this to camelcase".spaceToCamelCase()
    //实例化一个抽象类
    val myObject = object : MyAbstractClass() {
        override fun doSomething() {
            print("do something")
        }

        override fun sleep() {
            print("sleep")
        }
    }
    myObject.doSomething()
    //if-not-null缩写
    val files = File("Test").listFiles()
    println(files?.size)
    //if_not-null-else缩写
    val files02 = File("Test").listFiles()
    println(files?.size ?: "empty")
    val fileSize = files?.size ?: run { }
    println(fileSize)
    //if null 执行一个语句
    val values = mutableMapOf("email" to 1)
    val email = values["email"] ?: throw IllegalStateException("Email is missing!")
    //在可能会空的集合中取第一元素
    val emails = listOf<Int>()
    val mainEmail = emails.firstOrNull() ?: ""
    //if not null 执行代码
    var value: Int? = 1;
//    var value: Int? = null;
    value?.let {}
    //映射可空值
    val mapped = value?.let {
        value = transformValue(it)
        println(value)
    } ?: 1
    println(mapped)
    println(transform("Red"))
    println(test())
    //if表达式
    val x = 1;
    val y = if (x == 1) {
        "one"
    } else if (x == 2) {
        "two"
    } else {
        "other"
    }
    println(arrayOfMinusOnes(3))
    ///对一个对象实例调用多个方法(with)
    val myTurtle = Turtle()
    with(myTurtle) {
        penDown()
        for (i in 1..4) {
            forward(100.0)
            turn(90.0)
        }
        penUp()
    }
    ///配置对象的属性(apply)
    val myRectangle = Rectangle().apply {
        var length = 4
        var breadth = 5
        var color = 0xFAFAFA
    }
    ///java 7 的try-with-resource
    val stream = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        Files.newInputStream(Paths.get("/some/file.txt"))
    } else {
        TODO("VERSION.SDK_INT < O")
    }
    stream.buffered().reader().use { reader ->
        println(reader.readText())
    }
    ///可空布尔值
    val b: Boolean? = true
    if (b == true) else {
    }
    ///交换两个变量
    var a1 = 1
    var b1 = 2
    a1 = b1.also { b1 = a1 }
    fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")
}

//单表达式函数
fun theAnswer() = 42
fun theAnswer002(): Int {
    return 42
}

//单表达式函数
fun transform002(color: String): Int = when (color) {
    "Red" -> 0
    "Green" -> 1
    "Blue" -> 2
    else -> throw IllegalStateException("error")
}

//返回类型为Unit的方法的构建器风格用法
fun arrayOfMinusOnes(size: Int): IntArray {
    return IntArray(size).apply { fill(-1) }
}

//try-catch
fun test() {
    val result = try {
        println("try something")
    } catch (e: ArithmeticException) {
        throw IllegalStateException(e)
    }
}

//返回when表达式
fun transform(color: String): Int {
    return when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> throw IllegalArgumentException("Invalid color param value")
    }
}

fun transformValue(a: Int): Int {
    return 0
}

//创建单例
object Resource {
    val name = "Name"
}

//抽象类
abstract class MyAbstractClass {
    abstract fun doSomething()
    abstract fun sleep()
}

class Turtle {
    fun penDown() {}
    fun penUp() {}
    fun turn(degrees: Double) {}
    fun forward(pixels: Double) {}
}

//inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

基本类型

数字
package com.example.kotlinstudy.基本类型

val one = 1
val threeBillion = 30000000000
val oneLong = 1L
val oneByte: Byte = 1
val pi = 3.14
val oneDouble = 1.0
val e = 2.7111111111
val eFloat = 2.71545353454f
val oneMillin = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
fun main() {
    fun printDouble(d: Double) {
        println(d)
    }

    val i = 1
    val d = 1.0
    val f = 1.0f
    printDouble(d)
    println(oneMillin)

    ///JVM
    ///由于 JVM 对 -128 到 127 的整数(Integer)应用了内存优化,因此,a 的所有可空引用实际上都是同一对象。但是没有对 b 应用内存优化,所以它们是不同对象
    val a: Int = 10000
    //val a: Int = 10000
    val boxedA: Int? = a
    val anotherBoxA: Int? = a
    println(boxedA == anotherBoxA)
    //println(boxedA === anotherBoxA)

    //显示数字转换
    val b: Byte = 1
    val i1: Int = b.toInt()
    //很多请款无需显示类型转换
    val l = 1L + 3
    //数字运算
    println(1 + 2)
    println(2_500_000_000L - 1L)
    println(3.14 * 2.71)
    println(10.0 / 3)
    //整数除法
    val x = 5 / 2
    //println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
    println(x == 2)
    val x1 = 5L / 2
    println(x1 == 2L)
    val x3 = 5 / 2.toDouble()
    println(x3 == 2.5)
    //位运算
    val x4 = (1 shl 2) and 0x000FF000
    //浮点数比较
    println(Double.NaN == Double.NaN)                 // false
    println(listOf(Double.NaN) == listOf(Double.NaN)) // true
    println(0.0 == -0.0)                              // true
    println(listOf(0.0) == listOf(-0.0))              // false
    println(listOf(Double.NaN, Double.POSITIVE_INFINITY, 0.0, -0.0).sorted())
}
布尔
package com.example.kotlinstudy.基本类型

fun main() {
    val myTure: Boolean = true
    val myFalse: Boolean = false
    val boolNull: Boolean? = null
    println(myTure || myFalse)
    println(myTure && myFalse)
    println(!myTure)
}
字符串
package com.example.kotlinstudy.基本类型

val str = "abcd 123"
fun main() {
    val str = "abcd"
    for (c in str) {
        println(c)
    }
    println(str.uppercase())
    println(str)

    val s = "abc" + 1
    println(s + "def")

    val s1 = "hello, world!\n"
    val text = """
        for(c in "foo")
            print(c)
    """.trimIndent()
    println(text)

    //trimIndent取消前导空格
    val text1 = """
        |Tell me and I forget
        |Tech me and I remember
        |Involve me and I learn
        |(Benjamin Franklin)
    """.trimIndent()
    println(text1)

    //以竖线|为边界前缀
    val text2 = """
        |Tell me and I forget
        |Tech me and I remember
        |Involve me and I learn
        |(Benjamin Franklin)
    """.trimMargin("|")
    println(text2)

    val i = 10
    println("i = $i")

    val s2 = "abc"
    println("$s2.length is ${s2.length}")

    //插入美元字符
    val price = """
        ${'$'}_9.99
    """
    println(price)
}
数组
package com.example.kotlinstudy.基本类型

fun main() {
    val asc = Array(5) { i -> (i * i).toString() }
    asc.forEach { println(it) }

    val x: IntArray = intArrayOf(1, 2, 3)
    x[0] = x[1] + x[2]
    val arr001 = IntArray(5)
    val arr002 = IntArray(5) { 42 }
    var arr003 = IntArray(5) { it * 1 }
    arr001.forEach { println(it) }
    arr002.forEach { println(it) }
    arr003.forEach { println(it) }
}
无符号
package com.example.kotlinstudy.基本类型

val b: UByte = 1u
val s: UShort = 1u
val l: ULong = 1u
val a1 = 42u
val a2 = 0xFFFF_FFFF_FFFFu
val a = 1UL
类型检测与类型转换
package com.example.kotlinstudy.基本类型

fun main() {
    val obj = "";
    if (obj is String) {
        print("a String")
    }
    if (obj !is String) {
        print("Not a String")
    } else {
        print(obj.length)
    }
    //不安全的转换操作符
    val y = 1
    val x: String? = y as? String?
}

//智能转换类型
fun demo(x: Any) {
    if (x is String) {
        print(x.length)
    }
    if (x !is String) return
    print(x.length)
    if (x !is String || x.length == 0) {

    }
    if (x is String && x.length > 0) {
        print(x.length)
    }
    when (x) {
        is Int -> print(x + 1)
        is String -> print(x.length + 1)
        is IntArray -> print(x.sum())
    }
}

控制流程

For循环
package com.example.kotlinstudy.控制流程

fun main() {
    val collection = listOf<Int>()
    for (item in collection) print(item)
    val ints = listOf<Int>()
    for (item: Int in ints) {}
    for (i in 1..3) {
        println(i)
    }
    for (i in 6 downTo 0 step 2) {
        println(i)
    }
    val array = arrayOf("a", "b", "c")
    for(i in array.indices) {
        println(array[i])
    }
    for ((index,value ) in array.withIndex()) {
        println("the element at $index is $value")
    }
}
if表达式
package com.example.kotlinstudy.控制流程

fun main() {
    val a = 2
    val b = 2
    var max = a
    if (a < b) max = b
    if (a > b) {
        max = a
    } else {
        max = b
    }
    max = if (a > b) a else b
    val maxLimit = 1
    val maxOrLimit = if (maxLimit > a) maxLimit else if (a > b) a else b
    println("max is $max")
    println("maxOrLimit is $maxOrLimit")

    val max002 = if (a > b) {
        print("Choose a")
        a
    } else {
        print("Choose b")
        b
    }
    println(maxOrLimit)
}

//分支是简单布尔值
fun test() {
    val y = 1
    val x = 1
    fun Int.isOdd(): Boolean {
        return this%2 != 0
    }
    fun Int.isEven(): Boolean {
        return this%2 == 0
    }
    when {
        x.isOdd() -> print("x is odd")
        y.isEven() -> print("y is even")
        else -> print("x+y is odd")
    }
}


enum class Bit {
    ZERO, ONE
}

val numericValue = when (Bit.ONE) {
    Bit.ONE -> 1
    Bit.ZERO -> 0
    //else不需要,因为枚举类型都覆盖了
}

enum class Color {
    RED, GREEN, BLUE
}
when表达式
package com.example.kotlinstudy.控制流程

fun main() {
    //When表达式
    val x = 1;
    when (x) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        3, 4 -> print("1 or 2")
        else -> print("x is neither 1 nor 2")
    }

    //检测一个值在或者不在一个区间或者集合中
    val validNumbers = listOf(1, 2, 3)
    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 hasPrefix(x: Any) = when (x) {
        is String -> x.startsWith("prefix")
        else -> false
    }
//fun Request.getBody() =
//    when (val response = executeRequest()) {
//        is Success -> response.body
//        is HttpError -> throw HttpException(response.status)
//    }
    //
}
while循环
package com.example.kotlinstudy.控制流程

fun main() {
    var x = 0;
    while (x > 0) {
        x--
    }
    do {
        val y = retrieveData()
    } while (y != null) // y 在此处可见
}

fun retrieveData(): Int {
    return 1
}
异常
package com.example.kotlinstudy.控制流程

fun main() {
    //Try是一个表达式
    val c = 5
    val b = 1
    val a: Int? = try {
        c + b
    } catch (e: NumberFormatException) {
        null
    }
    //Nothing类型
    //val s = person.name ?: throw IllegalArgumentException("Name required")
    //当你调用该函数时,编译器会知道在该调用后就不再继续执行了:
    //val s = person.name ?: fail("Name required")
    //print(s)
    //如果用 null 来初始化一个要推断类型的值,而又没有其他信息可用于确定更具体的类型时,编译器会推断出 Nothing? 类型:
    val x = null  “x”具有类型 `Nothing?`
    val l = listOf(null) // “l”具有类型 `List<Nothing?>
}

//throw
fun throwTest() {
    throw Exception("Hi There!")
}

//try catch
fun tryTest() {
    try {

    } catch (e: NumberFormatException) {

    } finally {

    }
}

//受检异常
//Appendable append(CharSequence csq) throw IOException

//Nothing表示不会返回的函数
fun fail(message: String): Nothing {
    throw IllegalArgumentException(message);
}



返回与跳转
package com.example.kotlinstudy.控制流程

fun main() {
//    val s = person.name ?: return

    loop@ for (i in 1..100) {
        for (j in 1..100) {
            if (j > 2) {
                println(j)
                //continue@loop
                break@loop
            }
        }
    }

    foo()
    println()
    foo002()
    println()
    foo003()
    println()
    foo004()
    println()
    foo005()
}

fun foo() {
    listOf<Int>(1, 2, 3, 4, 5).forEach {
        if (it == 3) {
            return
        }
        print(it)
    }
}

fun foo002() {
    listOf<Int>(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) {
            return@lit
        }
        print(it)
    }
}

fun foo003() {
    listOf<Int>(1, 2, 3).forEach {
        if (it == 3) return@forEach
        print(it)
    }
}

fun foo004() {
    listOf<Int>(1, 2, 3).forEach(fun(value: Int) {
        if (value == 3) return
        print(value)
    })
}

//当要返一个回值的时候,解析器优先选用标签限定的返回:
fun foo005() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop 1
            print(it)
        }
    }
}

类与对象

构造函数

一个类可以有一个主构造函数或者多个次构造函数

class Person construct(name: String) {}

若没有带任何注解或者可见性修饰符,可以省constructor

class Person(name: String) {}

初始化代码放在init

class InitOrderDemo(name: String) {
	val firstProperty = "First property"
	val init {
		println("First")
	}
	val secondProperty = "Second property"
	init {
		println("Second")
	}
}
fun main() {
	InitOrderDemo("hello")
}

类体内声明属性初始化

class Customer(name:String) {
	val customerKey = name.uppercase()
}

声明属性从主构造初始化

class Person(val name: String = "", var isEmployed: Boolean = true)
次构造函数
class Person(val pets: MutableList<Pet> = mutableListOf())
class Pet {
	constructor(owner: Person) {
		owner.pets.add(this)
	}
}

关键词this调用另一个构造函数

class Person(val name: String) {
	val children: MutableList<Person> = mutableListOf()
	constructor(name: String, parent: Person) : this(name) {
		parent.children.add(this)
	}
}
创建类的实例
val invoice = Invoice()
抽象类
abstract class Polygon {
	abstract fun draw()
}
class Rectangle : Polygon() {
	override fun draw() {}
}

抽象成员覆盖非抽象的开放成员

open class PolygonExample {
    open fun draw() {

    }
}
abstract class WildShape : PolygonExample() {
    abstract override fun draw()
}

继承

隐式继承Any

open class Base(p: Int)
class BaseExtend(p: Int) : Base(p)

使用super调用基类的构造函数

class MyView : View {
    constructor(ctx: Context) : super(ctx)
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
覆盖方法

添加显示修饰符,使方法能够被覆盖

//覆盖方法
open class Shape {
    open fun draw() {}
    fun fill() {}
}

open class Circle() : Shape() {
    override fun draw() {

    }
    //禁止再覆盖
//    final override fun draw() {
//
//    }
}
覆盖属性
//覆盖属性
open class Shape2 {
    open val vertexCount: Int = 0
}

class Rectangle2 : Shape2() {
    override val vertexCount = 4
}

var可以override覆盖 val属性

interface Shape3 {
    val vertexCount: Int
}

class Rectangle3(override val vertexCount: Int = 4) : Shape3
class Polygon3 : Shape3 {
    override var vertexCount: Int = 0
}
派生类初始化顺序

先是完成基类初始化,再是派生类

使用super调用超类的属性和方法
open class Rectangle4 {
    open fun draw() {
        println("Drawing a rectangle")
    }

    val borderColor: String get() = "black"
}

class FilledRectangle : Rectangle4() {
    override fun draw() {
        super.draw()
        println("Filling the rectangle")
    }

    val fillColor: String get() = super.borderColor
}
内部类访问外部类的超类
open class Rectangle {
    open fun draw() { println("Drawing a rectangle") }
    val borderColor: String get() = "black"
}

class FilledRectangle: Rectangle() {
    override fun draw() {
        val filler = Filler()
        filler.drawAndFill()
    }

    inner class Filler {
        fun fill() { println("Filling") }
        fun drawAndFill() {
            super@FilledRectangle.draw() // Calls Rectangle's implementation of draw()
            fill()
            println("Drawn a filled rectangle with color ${super@FilledRectangle.borderColor}") // Uses Rectangle's implementation of borderColor's get()
        }
    }
}

fun main() {
    val fr = FilledRectangle()
        fr.draw()
}
覆盖规则
open class Rectangle {
    open fun draw() { /* …… */ }
}

interface Polygon {
    fun draw() { /* …… */ } // 接口成员默认就是“open”的
}

class Square() : Rectangle(), Polygon {
    // 编译器要求覆盖 draw():
    override fun draw() {
        super<Rectangle>.draw() // 调用 Rectangle.draw()
        super<Polygon>.draw() // 调用 Polygon.draw()
    }
}

属性

val & var

val是只读,var是可变

使用属性
fun copyAddress(address: Address): Address {
    val result = Address()
    result.name = address.name;
    return result
}
getter & setter
///getter
class RectangleObject(val width: Int, val height: Int) {

    //    val area: Int
//        get() = this.width * this.height
    val area
        get() = this.width * this.height
    var areaText: String = ""
    var stringRepresentation: String
        get() = this.toString();
        set(value) {
            this.areaText = value
        }
    var setterVisibility: String = "abc"
        private set

//    var setterWithAnnotation: Any? = null
//        @Inject set // 用 Inject 注解此 setter

    //幕后字段
    var counter = 0
        set(value) {
            if (value >= 0)
                field = value
        }
    val isEmpty: Boolean
        get() = this.counter == 0
}
幕后字段
    //幕后字段
    var counter = 0
        set(value) {
            if (value >= 0)
                field = value
        }
    val isEmpty: Boolean
        get() = this.counter == 0
编译时常量
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED)
fun foo() {}
延迟属性
class MyTest {
    //延迟初始化属性与变量
    lateinit var subject: TestSubject

    @SetUp
    fun setup() {
        subject = TestSubject()
    }

    @Test
    fun test() {
        subject.method()  // 直接解引用
    }
}
//检查是否初始化
if (foo::bar.isInitialized) {
    println(foo.bar)
}

接口

package com.example.kotlinstudy.类与对象

import android.icu.text.Transliterator.Position

interface MyInterface {
    val prop: Int
    val propertyWithImplementation: String
        get() = "foo"

    fun bar()
    fun foo() {
        print(prop)
    }
}

class Child : MyInterface {
    override val prop: Int
        get() = 29

    override fun bar() {

    }
}

///接口继承
interface Named {
    val name: String
}

interface PersonA : Named {
    val firstName: String
    val lastName: String
    override val name: String
        get() = "$firstName $lastName"
}

data class Employee(
    override val firstName: String,
    override val lastName: String,
    val position: Position,
) : PersonA

///解决覆盖冲突
interface A {
    fun foo() {
        print("A")
    }
    fun bar()
}
interface B {
    fun foo() {
        print("B")
    }
    fun bar() {
        print("bar")
    }
}
class C : A {
    override fun bar() {
        print("bar")
    }
}
class D : A, B {
    override fun foo() {
        super<A>.foo()
        super<B>.foo()
    }

    override fun bar() {
        super<B>.bar()
    }
}

SAM

package com.example.kotlinstudy.类与对象

fun interface KRunnable {
    fun invoke()
}

//SAM转换
fun interface IntPredicate {
    fun accept(int: Int): Boolean
}

val isEven = object : IntPredicate {
    override fun accept(int: Int): Boolean {
        return int % 2 == 0
    }
}
val isEvenLambda = IntPredicate { it % 2 == 0 }
fun main() {
    println("Is 7 even? - ${isEvenLambda.accept(7)}")
    ::Printer
    println("Is 7 even? - ${isEven02(7)}")
}

interface Printer {
    fun print()
}

fun Printer(block: () -> Unit): Printer = object : Printer {
    override fun print() = block()
}

//函数式接口与类型别名比较
typealias IntPredicate02 = (i: Int) -> Boolean

val isEven02: IntPredicate02 = { it % 2 == 0 }

可见性修饰符

  • public 随处可见。
  • private 文件内可见。
  • internal 相同模块内可见。
  • protected 修饰符不适用于顶层声明。
  • private 类内部可见
  • protected 类内部可见和子类可见
  • internal 类声明的本模块内的任何客户端
  • public 类声明的任何客户端
构造函数

主构造函数需要加construct,默认为public

例子
package com.example.kotlinstudy.类与对象

//包
fun baz() {}
class Bar {}

public var bar: Int = 5
    private set
internal val boX = 6

///类成员
open class Outer {
    private val a = 1
    protected open val b = 3
    internal open val c = 3
    val d = 4

    protected class Nested {
        public val e: Int = 5
    }
}

class SubClass : Outer() {
    override val b: Int
        get() = 5
    override val c: Int
        get() = 7
}

class Unrelated constructor(outer: Outer) {

}

//构造函数
class TestC private constructor(a: Int) {

}

扩展

package com.example.kotlinstudy.类与对象

//扩展函数
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]
    this[index1] = this[index2]
    this[index2] = tmp;
}

fun main() {
    val list = mutableListOf(1, 2, 3)
    list.swap(0, 2)
    ///扩展是静态解析的
    open class Shape
    class Rectangle : Shape()

    fun Shape.getName() = "Shape"
    fun Rectangle.getName() = "Rectangle"
    fun printClassName(s: Shape) {
        println(s.getName())
    }
    printClassName(Rectangle())

    ///扩展函数与组内函数名一致时取组内函数
    class Example {
        fun printA() {
            println("A")
        }
    }

    fun Example.printA() {
        println("a")
    }
    Example().printA()

    ///重载函数不同签名成员函数
    class Example1 {
        fun printB() {
            println("B")
        }
    }

    fun Example1.printB(i: Int) {
        println("$i")
    }
    Example1().printB(1);

    ///可空接受者
    fun Any?.toString(): String {
        if (this == null) return "null"
        return toString()
    }

    //伴生对象的扩展
    MyClass.printCompanion()

    ///扩展的作用域
    val listA = listOf<String>("red", "green", "blue")
    listA.getLongestString()

    ///扩展声明为成员
    Connection(Host("kotl.in"), 443).connect()

    BaseCaller().call(Base3())   // “Base extension function in BaseCaller”
    DerivedCaller().call(Base3())  // “Base extension function in DerivedCaller”——分发接收者虚拟解析
    DerivedCaller().call(Derived3())  // “Base extension function in DerivedCaller”——扩展接收者静态解析
}

//扩展属性
val <T> List<T>.lastIndex: Int
    get() = size - 1

//伴生对象的扩展
class MyClass {
    companion object
}

fun MyClass.Companion.printCompanion() {
    println("companion")
}

///扩展声明为成员
class Host(val hostname: String) {
    fun printHostname() {
        print(hostname)
    }
}

class Connection(val host: Host, val port: Int) {
    fun printPort() {
        print(port)
    }

    fun Host.printConnectionString() {
        printHostname()
        print(":")
        printPort()
    }

    fun connect() {
        host.printConnectionString()
    }

    fun Host.getConnectionString() {
        toString() //调用Host.toString()
        this@Connection.toString() //调用Connection.toString()
    }
}

///
open class Base3 {

}

class Derived3 : Base3() {

}

open class BaseCaller {
    open fun Base3.printFunctionInfo() {
        println("Base extension function in BaseCaller")
    }

    open fun Derived3.printFunctionInfo() {
        println("Derived extension function in BaseCaller")
    }

    fun call(b: Base3) {
        b.printFunctionInfo()
    }
}

class DerivedCaller : BaseCaller() {
    override fun Base3.printFunctionInfo() {
        println("Base extension function in DerivedCaller")
    }

    override fun Derived3.printFunctionInfo() {
        println("Derived extension function in DerivedCaller")
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sheng_er_sheng

打赏是什么?好吃么

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值