Kotlin学习笔记1
2023-12-13 06:11:15
数组
/**
* 何时使用数组
*/
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() {
}
类的属性
文章来源:https://blog.csdn.net/u013837825/article/details/134951483
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!