kotlin学习
kotlin学习笔记
初识
- kotlin是一门用于现代多平台应用的编程语言,被广泛应用于Android平台的开发
- 特点:更有安全性(避免null指针)、可互操作(与java交互操作)、协程
适用的应用平台
学习内容概述
1、基础语法
掌握基本变量类型、声明(val、var)、循环语句、函数及类的定义使用等
-
字符串模板及格式
-
用$
-
val i = 10 println("i = $i") // i = 10 -
${}
-
val s = "abc" println("$s.length is ${s.length}") // abc.length is 3 -
字符串格式-- String.format()
-
val num = String.format("%07d", 31416) println(num) // 0031416 val floatNumber = String.format("%+.4f", 3.141592) println(floatNumber) // +3.1416 val helloString = String.format("%S %S", "hello", "world") println(helloString) // HELLO WORLD
-
-
var/val的区别
-
var:可变 val:不可变
-
推荐先使用val定义,可以避免被不小心修改,如果需要修改时再更改为var
-
-
数组创建、比较数组
-
数组创建
-
val simpleArray = arrayOf(1, 2, 3) println(simpleArray.joinToString()) // 1, 2, 3 val initArray = Array<Int>(3) { 0 } println(initArray.joinToString()) // 0, 0, 0 val asc = Array(5) { i -> (i * i).toString() } asc.forEach { print(it) } // 014916 -
比较数组:比较两个数组是否具有相同顺序的相同元素
-
val simpleArray = arrayOf(1, 2, 3) val anotherArray = arrayOf(1, 2, 3) // 比较 println(simpleArray.contentEquals(anotherArray)) // true
-
-
is操作符
-
检测对象是否符合给定类型
-
if (obj is String) { print(obj.length) } if (obj !is String) { // 与 !(obj is String) 相同 print("Not a String") }
-
-
if特殊用法
-
作为表达式可以返回值
-
// 作为表达式 max = if (a > b) a else b -
可以是代码块,表达式作为返回值
-
val max = if (a > b) { print("Choose a") a // 返回a } else { print("Choose b") b }
-
-
when
-
类比Switch, else->default,可以使用任意表达式(不一定要常量)
-
when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { print("x is neither 1 nor 2") } } when (x) { in 1..10 -> print("x is in the range") // 1..10 区间 [1,10] !in 10..20 -> print("x is outside the range") else -> print("none of the above") }
-
-
类型转换
-
fun demo(x: Any) { if (x is String) { print(x.length) // x 自动转换为字符串 } }
-
2、函数
了解函数式编程思想,能熟练掌握函数应用
-
使用
-
通过fun关键字声明,参数可以有默认值
-
fun double(x: Int): Int { return 2 * x } // 每个参数必须有显式类型 -
单表达式函数
-
fun sum(x: Int, y: Int): Int { return x + y } // 缩短 fun sum(x: Int, y: Int) = x + y
-
-
lambda表达式
-
fun uppercaseString(text: String): String { return text.uppercase() } // 改为lambda表达式 val upperCaseString = { text: String -> text.uppercase() } // ->前面是参数,后面是返回值val numbers = listOf(1, -2, 3, -4, 5, -6) val positives = numbers.filter ({ x -> x > 0 }) // 参数x,获取列表的每个元素,返回x>0的集合 val isNegative = { x: Int -> x < 0 } val negatives = numbers.filter(isNegative) // 参数x,获取列表的每个元素,返回x<0的集合 println(positives) // [1, 3, 5] println(negatives) // [-2, -4, -6]
-
3、面向对象编程
理解类和对象的作用,掌握主构造和次构造以及各种类
-
构造函数
-
在 Kotlin 中的一个类有一个主构造函数并可能有一个或多个次构造函数。
-
主构造函数
-
在类头中声明,它跟在类名与可选的类型参数后,初始化类实例及其属性。
-
class Person constructor(firstName: String) { /*……*/ } // 没有注解时constructor可以省略不写 属性可以写默认值 -
如果要在对象创建期间运行一些代码,使用init关键字,初始化块按照它们出现在类体中的顺序执行
-
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 Person(val name: String) { val children: MutableList<Person> = mutableListOf() constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
-
-
创建类实例
-
val invoice = Invoice() val customer = Customer("Joe Smith")
-
-
-
继承
-
共同超类:Any,有三个默认方法:equals,hashCode、toString
-
用open关键字开放继承
-
open class Base(p: Int) // 开放继承 class Derived(p: Int) : Base(p)
-
-
覆盖(了解):Kotlin 对于可覆盖的成员以及覆盖后的成员需要显式修饰符
-
open class Shape { open fun draw() { /*……*/ } fun fill() { /*……*/ } } // open 开放覆盖 override禁止覆盖 class Circle() : Shape() { override fun draw() { /*……*/ } }
-
-
-
属性
-
Getter与Setter
-
// 声明一个属性的完整语法
var <propertyName>[: <PropertyType>] [= <property_initializer>] [<getter>] [<setter>] // 初始器(initializer)、getter 和 setter 都是可选的 class Rectangle(val width: Int, val height: Int) { val area: Int // 类型可以省略 val area get() = this.width * this.height get() = this.width * this.height }
-
-
接口
-
既包含抽象方法的声明也包含实现,使用关键字interface定义
-
interface MyInterface { val prop: Int // 抽象的 val propertyWithImplementation: String get() = "foo" fun foo() { print(prop) } } class Child : MyInterface { // 实现接口(一个或多个) override val prop: Int = 29 } -
接口可以从其他接口派生
-
interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } data class Employee( // 不必实现“name” override val firstName: String, override val lastName: String, val position: Position ) : Person -
覆盖冲突:实现多个接口时,可能遇到同一方法继承多个实现的问题,需要实现从多个接口继承的所有方法,并指明应该如何实现它们。
-
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") } // foo已实现,重写bar } class D : A, B { override fun foo() { // A、B的foo方法不一样,需要自己重写定义 super<A>.foo() super<B>.foo() } override fun bar() { super<B>.bar() } } -
函数式接口:只有一个抽象方法的接口,可以有多个非抽象成员,只能有一个抽象成员
-
fun interface KRunnable { fun invoke() }
-
-
-
可见性修饰符
-
如果你不使用任何可见性修饰符,默认为public ,这意味着你的声明将随处可见。
-
如果你声明为
private,它只会在声明它的文件内/类内部可见。 -
如果你声明为
internal,它会在相同模块内随处可见。 -
protected修饰符不适用于顶层声明,在本类和子类中可见。 -
// 文件名:example.kt package foo private fun foo() { …… } // 在 example.kt 内可见 public var bar: Int = 5 // 该属性随处可见 private set // setter 只在 example.kt 内可见 internal val baz = 6 // 相同模块内可见
-
-
扩展(了解)
-
对一个类或接口扩展新功能而无需继承该类
-
可以为一个你不能修改的、来自第三方库中的类或接口编写一个新的函数。 这个新增的函数就像那个原始类本来就有的函数一样,可以用寻常方式调用。 这种机制称为扩展函数。
-
fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = this[index1] // “this”对应该列表 this[index1] = this[index2] this[index2] = tmp } // MutableList<Int>增加swap函数
-
-
数据类
-
主要用于保存数据,自动附带其他成员函数。这些成员函数允许您轻松地将实例打印为可读输出、比较类的实例、复制实例等
-
data class User(val name: String, val age: Int) -
主要成员函数
函数 描述 equals() 比较类的实例。 copy() 通过复制另一个类实例来创建类实例,该实例可能具有一些不同的属性。 toString() 打印类实例及其属性的可读字符串。
-
4、高级知识
-
泛型
-
类似java的类型参数
-
class Box<T>(t: T) { var value = t }
-
-
集合
-
list:按添加顺序存储项目,并允许重复项目
-
val readOnlyShapes = listOf("triangle", "square", "circle") // 只读 println(readOnlyShapes) // [triangle, square, circle] val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle") // 可变 println(shapes) // [triangle, square, circle] -
set:无序,只存储唯一项
-
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry") // 只读 // 只保留一个cherry val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry") // 可改 println(readOnlyFruit) // [apple, banana, cherry] -
map:将内容存储为键值对,用key来访问
-
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100) //只读 println(readOnlyJuiceMenu) // {apple=100, kiwi=190, orange=100} val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100) // 可改 println(juiceMenu) // {apple=100, kiwi=190, orange=100}
-
-
异常
-
可以捕获错误信息
-
try { // 一些代码 } catch (e: SomeException) { // 处理错误的程序 } finally { // 可选的 finally 块 一定会执行 }
-
-
空安全
-
值可能为空时,需要用“?”标记
-
fun parseInt(str: String): Int? { // ... }
-
5、多平台开发
-
安装Android Studio
-
MyFirstApp/: 项目的根目录。
.idea/: Android Studio 的配置目录,包含项目的 IDE 设置,通常不需要手动更改。
app/: 应用模块的主目录。
src/: 源代码和资源文件存放的目录。
main/: 主要的源代码和资源目录。
java/: Java 或 Kotlin 源代码的目录。
res/: 资源文件的目录。
drawable/: 存放图像资源。
layout/: 存放布局文件,定义应用界面的结构。
mipmap/: 存放应用的图标和启动图。
values/: 存放字符串、颜色、尺寸等资源。
AndroidManifest.xml: 应用的清单文件,包含应用的配置信息、权限和组件声明。
build.gradle: 应用级别的构建配置文件,定义了应用的依赖、插件和其他构建设置。
build.gradle: 项目级别的构建配置文件,定义了整个项目的配置和依赖。
gradle/: 存放与 Gradle 构建系统相关的文件和目录。
gradle/wrapper/: Gradle Wrapper 文件,用于自动下载和使用指定版本的 Gradle。
settings.gradle: 项目的全局设置文件,定义了项目包含的模块。
更多推荐


所有评论(0)