变量
变量是存储单项数据的容器,必须先声明变量,才可以使用。
常见的数据类型:Int、Double、String、Boolean
val
关键字用于定义只读变量,一旦赋值就不能更改。
var
关键字用于定义可变变量。
在Kotlin
中,建议尽可能使用val
,而不是var
声明变量
例如:
val count: Int = 2 // 不可变变量
println("this count is $count") //$count 输出变量
var number: Int = 2 // 可变变量
number++
函数
声明函数时,需要使用fun
关键字,并在 {}
中添加代码用于执行某个任务的指令。
声明函数
如果不指定返回值类型,默认返回值类型是Unit
类型。Unit
表示函数不会返回值,所以不需要使用 return
语句。如果指定了返回值类型,则必须使用return
语句。
例如:
fun sum(num1: Int, num2: Int): Int{
return num1 + num2
}
// 按照形参传递
print(sum(2,1))
// 调用函数时为实参命名。使用具名实参时,您可以对实参重新排序,而不会影响输出
// 按照具名实参传递
print(sum(num2 = 1,num1 = 2))
// 指定默认实参,以便在调用函数时省略该实参
// 如果没有传入 num1, 则num1按 10 来计算
fun sum(num1: Int = 10, num2: Int): Int{
return num1 + num2
}
条件语句
if/else 语句
例如 实现红绿灯
fun main() {
val trafficLightColor = "Black"
if (trafficLightColor == "Red") {
println("Stop")
} else if (trafficLightColor == "Yellow") {
println("Slow")
} else if (trafficLightColor == "Green") {
println("Go")
} else {
println("Invalid traffic-light color")
}
}
when 语句
在 Kotlin 中,当处理多个分支时,可以使用 when 语句。类似 java 中的 switch 语句。
使用 when
语句实现红绿灯
fun main() {
val trafficLightColor = "Yellow"
when (trafficLightColor) {
"Red" -> println("Stop")
"Yellow" -> println("Slow")
"Green" -> println("Go")
else -> println("Invalid traffic-light color")
}
}
when
语句中多个条件,用英文逗号 (,) 处理。
when
语句中使用 in
关键字和一个值范围,如需使用某个范围内的值,请添加一个表示范围起点的数字,后跟两个不含空格的点,然后使用另一个表示范围终点的数字作为结尾。
when
语句中使用 is
关键字作为条件,以检查所评估值的数据类型。
fun main() {
val x: Any = 20
when (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 an integer number.")
}
}
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" -> "Proceed with caution."
"Green" -> "Go"
else -> "Invalid traffic-light color"
}
println(message)
}
Kotlin 中的null
kotlin 不允许为变量赋值为 null
,只有当您明确让某个变量可以存储 null
值时,该变量才属于可为null
类型。如需在 Kotlin 中声明可为null
的变量,您需要在相应类型的末尾添加?
运算符
如果需要访问可为 null
的变量时
可使用 ?.
安全调用运算符访问可为 null 变量的方法或属性
也可使用 !!
非 null 断言运算符来访问可为 null 的变量的方法或属性。⚠️ 使用!!
必须保证变量不为null,否则会在执行期间崩溃
也可结合 if/else
语句使用
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor.length)//错误 执行出错
println(favoriteActor?.length)//对于可为null类型的值
println(favoriteActor!!.length)
if (favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.") }
}
val lengthOfName = if(favoriteActor != null) {
favoriteActor.length
} else {
0
}
使用 ?: Elvis 运算符
?:
Elvis 运算符可以与?.
安全调用运算符搭配使用。如果搭配使用?:
Elvis 运算符,您便可以在?.
安全调用运算符返回null
时添加默认值。这与if/else
表达式类似,但更为常用。
如果该变量不为null
,则执行?:
Elvis 运算符之前的表达式;如果变量为 null
,则执行?:
Elvis 运算符之后的表达式。
个人认为:?:
可以理解为三目运算符
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = favoriteActor?.length ?: 0
println("The number of characters in your favorite actor's name is $lengthOfName.")
类和对象
类定义以class
关键字开头,后面依次跟名称和一对大括号。左大括号之前的语法部分也称为类标头。在大括号之间,您可以指定类的属性和函数。
类由以下三大部分组成:
属性:用于指定类对象属性的变量。
方法:包含类的行为和操作的函数。
构造函数:一种特殊的成员函数,用于在定义类的整个程序中创建类的实例
示例:
// 定义类
class SmartDevice {
// 定义类的属性
val name = "Android TV"
val category = "Entertainment"
var deviceStatus = "online"
// 定义类的方法
fun turnOn(){
println("Smart device is turned on.")
}
fun turnOff(){
println("Smart device is turned off.")
}
}
fun main(){
// 创建类的对象
val smartTvDevice = SmartDevice()
//调用类的属性
println("Device name is: ${smartTvDevice.name}")
// 调用类的方法
smartTvDevice.turnOn()
smartTvDevice.turnOff()
}
构造函数
辅助构造函数声明:辅助构造函数定义以constructor
关键字开头,后跟圆括号。可视情况在圆括号中包含辅助构造函数所需的形参。
主要构造函数初始化:初始化以冒号开头,后面依次跟this
关键字和一对圆括号。可视情况在圆括号中包含主要构造函数所需的形参。
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 -> "unknown"
}
}
...
}
类之间的关系
Kotlin 中,所有类默认都是最终类,也就是说您无法扩展这些类,因此必须定义类之间的关系,可在父类中的 class
关键字之前,添加open
关键字对其父类进行扩展。同样,如果需要继承父类中的方法,也需要在方法前添加open
关键字。
open class SmartDevice {
...
var deviceStatus = "online"
open fun turnOn() {
// function body
}
open fun turnOff() {
// function body
}
}
class SmartLightDevice(name: String, category: String) :
SmartDevice(name = name, category = category) {
var brightnessLevel = 0
override fun turnOn() {
deviceStatus = "on"
brightnessLevel = 2
println("$name turned on. The brightness level is $brightnessLevel.")
}
// override 关键字会告知 Kotlin 运行时去执行子类所定义方法中包含的代码。
override fun turnOff() {
deviceStatus = "off"
brightnessLevel = 0
println("Smart Light turned off")
}
fun increaseBrightness() {
brightnessLevel++
}
}
使用super
关键字在子类中重复使用父类代码
可见性修饰符
Kotlin 提供了以下四种可见性修饰符:
public:默认的可见性修饰符。可让系统在任何位置访问声明。对于您想在类外部使用的属性和方法,请标记为 public。
private:可让系统在相同类或源文件中访问声明。
某些属性和方法可能仅在类的内部使用,而且您不一定想让其他类使用。您可以使用 private 可见性修饰符标记这些属性和方法,以确保其他类不会意外访问它们。
protected:可让系统在子类中访问声明。对于您想在定义它们的类及其子类中使用的属性和方法,请使用 protected 可见性修饰符进行标记。
internal:可让系统在相同模块中访问声明。internal 修饰符与 private 类似,但您可以从类的外部访问内部属性和方法,只要是在相同模块中进行访问即可
定义属性委托
创建属性委托的语法是以变量声明开头,后面依次跟 by
关键字以及用于为属性处理getter
和setter
函数的委托对象。
若要实现您可以委托实现的目标类,您必须熟悉接口。接口是实现它的类必须遵循的协议,侧重于操作的“内容”,而不是操作的“方式”。简而言之,接口可帮助您实现抽象。
class RangeRegulator(
initialValue: Int,
private val minValue: Int,
private val maxValue: Int
) : ReadWriteProperty<Any?, Int> {
var fieldData = initialValue
override 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) {
private var speakerVolume by RangeRegulator(initialValue = 0, minValue = 0, maxValue = 100)
private var channelNumber by RangeRegulator(initialValue = 1, minValue = 0, maxValue = 200)
...
}
class SmartLightDevice(deviceName: String, deviceCategory: String) :
SmartDevice(name = deviceName, category = deviceCategory) {
private var brightnessLevel by RangeRegulator(initialValue = 2, minValue = 0, maxValue = 100)
...
}