在kotlin中编写条件语句
if条件语句
fun main() {val trafficLight = "gray"if (trafficLight == "red") {println("Stop!")} else if (trafficLight == "green") {println("go!")} else if (trafficLight == "yellow"){println("Wait wait...")} else {println("invalid light color")}
}
when语句处理多分支
如果分支数量大于两个,尽可能使用when,提到代码的可读性。
fun main() {val trafficLight = "gray"when (trafficLight) {"red" -> println("Stop!")"green" -> println("go!")"yellow" -> println("Wait wait...")else -> println("invalid light color")}}
fun main() {val x = 3when (x) {2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")3 -> println("x is a prime number between 1 and 10.")5 -> println("x is a prime number between 1 and 10.")7 -> println("x is a prime number between 1 and 10.")else -> println("x isn't a prime number between 1 and 10.")}
}
fun main() {val x = 3when (x) {2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")else -> println("x isn't a prime number between 1 and 10.")}
}
fun main() {val x: Any = 4when (x) {2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")is Int -> println("x is an integer number, but not between 1 and 10.")else -> println("x isn't a prime number between 1 and 10.")}
}
使用if/else 和when作为表达式
fun main() {val trafficLightColor = "Black"val message = if (trafficLightColor == "Red") "Stop"else if (trafficLightColor == "Yellow") "Slow"else if (trafficLightColor == "Green") "Go"else "Invalid traffic-light color"println(message)
}
fun main() {val trafficLightColor = "Amber"val message = when(trafficLightColor) {"Red" -> "Stop""Yellow", "Amber" -> "Slow""Green" -> "Go"else -> "Invalid traffic-light color"}
}
总结
Kotlin 中使用可为null性
在kotlin中声明变量时需要立即赋值。
fun main() {var favoriteActor: String? = "Sandra Oh"val lengthOfName = favoriteActor?.length ?: 0println("The number of characters in your favorite actor's name is $lengthOfName.")
}
总结
kotlin使用类和对象
创建类的实例
定义类的方法和属性,和之前学到的定义函数和变量是一样的,不同的是要把函数和变量放在类的内部。
属性中的getter和setter函数
这两个函数主要是根据特殊要求的属性,进行操作,例如某个属性不能为负数,或者读取的某个属性一定为大写等。这种情况下就要定义可变属性。
定义可变属性的语法
如果你没有定义get /set 函数,编译器会自动生成get/set函数:
- 以
val
关键字开头。 val
类型的变量为只读变量,因此不含set()
函数。
定义构造函数
主要构造函数:一个类只能有一个主要构造函数(在类标头中定义)。主要构造函数可以是默认构造函数,也可以是形参化构造函数。主要构造函数没有主体(表示其中不能不包含任何代码)
定义主要构造函数的完整语法如下:
辅助构造函数:一个类可以有多个辅助构造函数。您可以定义包含形参或不含形参的辅助构造函数。辅助构造函数可以初始化类,具有包含初始化逻辑的主体。如果类有主要构造函数,则每个辅助构造函数都需要初始化该主要构造函数。
定义辅助构造函数的完整代码如下:
class SmartDevice(val name: String, val category: String) {var deviceStatus = "online"constructor(name: String, category: String, statusCode: Int) : this(name,category) {deviceStatus = when (statusCode) {0 -> "offline"1 -> "online"else -> "unkown"}print("deviceStatus = ${deviceStatus}\n")}fun turnOn() {println("Smart device is turned on.${name}")}fun turnOff() {println("Smart device is turned off.${category}")}
}
fun main() {val smartTvDevice = SmartDevice(name = "apxu", category = "ok",statusCode = 1)smartTvDevice.turnOn()smartTvDevice.turnOff()
}
实现类之间的关系
继承
定义可扩展类,需要在class前面添加 open关键字:
继承语法如下所示:
SmartTvDevice的constructor定义没有指定属性是可变还是不可变的,这说明deviceName和deviceCategory形参只是constructor形参,而不是类的属性。
子类中调用父类的方法super.functionname()
父类:
open class SmartDevice(val name: String, val category: String) {var deviceStatus = "online"open fun turnOn() {deviceStatus = "on"}open fun turnOff() {deviceStatus = "off"}
}
子类:
class SmartTvDevice(deviceName: String, deviceCategory: String) :SmartDevice(name = deviceName, category = deviceCategory) {var speakerVolume = 2set(value) {if (value in 0..100) {field = value}}var channelNumber = 1set(value) {if (value in 0..200) {field = value}}fun increaseSpeakerVolume() {speakerVolume++println("Speaker volume increased to $speakerVolume.")}fun nextChannel() {channelNumber++println("Channel number increased to $channelNumber.")}override fun turnOn() {super.turnOn()println("$name is turned on. Speaker volume is set to $speakerVolume and channel number is " +"set to $channelNumber.")}override fun turnOff() {super.turnOff()println("$name turned off")}
}
可见性修饰符
public,private,protected,internal
Kotlin 提供了以下四种可见性修饰符:
public
:默认的可见性修饰符。可让系统在任何位置访问声明。对于您想在类外部使用的属性和方法,请标记为 public。private
:可让系统在相同类或源文件中访问声明。
某些属性和方法可能仅在类的内部使用,而且您不一定想让其他类使用。您可以使用 private
可见性修饰符标记这些属性和方法,以确保其他类不会意外访问它们。
protected
:可让系统在子类中访问声明。对于您想在定义它们的类及其子类中使用的属性和方法,请使用protected
可见性修饰符进行标记。internal
:可让系统在相同模块中访问声明。internal 修饰符与 private 类似,但您可以从类的外部访问内部属性和方法,只要是在相同模块中进行访问即可。
为属性指定可见性修饰符
open class SmartDevice(val name: String, val category: String) {...private var deviceStatus = "online"...
}
您也可以将可见性修饰符设置为 setter 函数,并将修饰符放在 set
关键字之前。语法如下图所示:
为方法指定可见性修饰符
为构造函数指定可见性修饰符
1.修饰符在类名之后,constuctor关键字之前
2.及时构造函数没有参数,也要保留constuctor关键字和()
open class SmartDevice protected constructor (val name: String, val category: String) {...}
为类指定可见性修饰符
internal open class SmartDevice(val name: String, val category: String) {...}
理想情况下,您应努力严控属性和方法的可见性,因此请尽可能通过 private
修饰符来声明属性和方法。如果您无法确保它们私有,请使用 protected
修饰符;如果您无法确保它们受到保护,请使用 internal
修饰符;如果您无法确保它们仅在内部使用,请使用 public
修饰符。
指定适当的可见性修饰符
定义属性委托
有很多属性的内容有相同的约束,例如:音量,频道的等都是0~100之间,如果每个属性都写一个setter,就会有很多相同的代码,为了简化代码,我们可以使用委托。
定义委托语法如下:
若要实现您可以委托实现的目标类,您必须熟悉接口。
创建接口语法如下所示:
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KPropertyclass RangeRegulator(initialValue: Int,private val minValue: Int,private val maxValue: Int
) : ReadWriteProperty<Any?, Int> {var fieldData = initialValueoverride fun getValue(thisRef: Any?, property: KProperty<*>): Int {return fieldData}override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {if (value in minValue..maxValue) {fieldData = value}}
}
class SmartTvDevice(deviceName: String, deviceCategory: String) :SmartDevice(name = deviceName, category = deviceCategory) {override val deviceType = "Smart TV"private var speakerVolume by RangeRegulator(initialValue = 2, minValue = 0, maxValue = 100)private var channelNumber by RangeRegulator(initialValue = 1, minValue = 0, maxValue = 200)...}
kotlin使用函数类型和lambda表达式
fun关键字来声明函数,使用fun关键字声明函数可供调用,函数也属于数据类型,可以将函数存储在变量中,将函数传递到函数,或从函数返回函数等。这一切都可以通过lambda表达式来实现。
只需函数引用运算符::,语法如下:
fun main() {val trickFunction = ::trick
}fun trick() {println("No treats!")
}
使用 lambda 表达式重新定义函数
lambda表达式提供了简洁的语法定义函数,不用fun关键字。我们可以直接将lambda表达式存储在变量中,不需要对其他函数进行函数引用。
fun main() {//val trickFunction = ::trickval trickFunction = tricktrick()trickFunction()
}val trick = {println("No treats!")
}//fun trick() {
// println("No treats!")
//}
在kotlin中使用函数类型和lambda表达式
如果需要将函数存储在变量中需要使用函数引用运算符(::)。语法如下所示:
fun main() {val trickFunction = ::trick
}fun trick() {println("No treats!")
}
使用lambda表达式重新定义函数
lambda表达式提供了简洁的语法来定义函数,无需使用fun关键字。我们可以直接将lambda表达式存储在变量中,无需对其他函数进行函数引用。
在赋值运算符(=)前面,添加var或val关键字,后跟变量名称,以供我们在调用函数时使。赋值运算符(=)后面是lambda表达时,它由一对大括号构成,大括号中的内容是函数正文。语法如下:
fun main() {val trickFunction = tricktrick()trickFunction()
}val trick = {println("No treats!")
}
将函数用作数据类型
fun main() {val trickFunction = tricktrick()trickFunction()treat()
}
val trick = {println("No treats!")
}
val treat: () -> Unit = {println("Have a treat!")
}
将函数作为返回值
语法:
fun main() {val treatFucntion = trickOrTreat(false)val trickFucntion = trickOrTreat(true)treatFucntion()trickFucntion()
}
fun trickOrTreat(isTrick:Boolean) -> Uint {if (isTrick) {return trick} else {return treat}
}
val trick = {println("No treats!")
}
val treat = {println("Have a treat!")
}
讲一个函数作为参数传递给另一个函数
fun main() {val coins: (Int) -> String = { quantity ->"$quantity quarters"}val cupcake: (Int) -> String = {"Have a cupcake!"}val treatFunction = trickOrTreat(false,coins)val trickFunction = trickOrTreat(true,cupcake)treatFunction()trickFunction()
}
fun trickOrTreat(isTrick: Boolean, extraTreat: (Int) -> String): () -> Unit {if (isTrick) {return trick} else {println(extraTreat(5))return treat}
}
val trick = {println("No treat")
}val treat = {println("Have treat")
}
可为null的函数类型
fun trickOrTreat(isTrick: Boolean, extraTreat: ((Int) -> String)?): () -> Unit {if (isTrick) {return trick} else {if (extraTreat != null) {println(extraTreat(5))}return treat}
}fun main() {val coins: (Int) -> String = { quantity ->"$quantity quarters"}val treatFunction = trickOrTreat(false, coins)val trickFunction = trickOrTreat(true, null)treatFunction()trickFunction()
}
省略lambda参数名
将lambda表达式直接传入函数
fun main() {val treatFunction = trickOrTreat(false, { "$it quarters" })val trickFunction = trickOrTreat(true, null)treatFunction()trickFunction()
}
使用尾随lambda语法
当函数类型是函数的最后一个参数时,您可以使用另一个简写选项来编写 lambda。在这种情况下,您可以将 lambda 表达式放在右圆括号后面以调用函数。语法如下图所示:
val treatFunction = trickOrTreat(false) { "$it quarters" }
使用repeat()函数
如果一个函数返回或接受另一个函数作为实参,该函数就称为高阶函数,trickOrTreat()
函数是一个高阶函数示例,因为它接受 ((Int) -> String)?
类型的函数作为参数,并返回 () -> Unit
类型的函数。
Kotlin 提供了几个有用的高阶函数,您可以利用新掌握的 lambda 知识对这些函数加以利用。
repeat() 函数就是这样一种高阶函数。repeat()
函数是使用函数表达 for
循环的简洁方式。在后续单元中,您会经常使用该函数以及其他高阶函数。repeat()
函数具有以下函数签名:
repeat(times: Int, action: (Int) -> Unit)
fun main() {val treatFunction = trickOrTreat(false) { "$it quarters" }val trickFunction = trickOrTreat(true, null)repeat(4) {treatFunction()}trickFunction()
}