1,基础语法
1.1 可变变量与不可变变量
可以多次赋值的变量是可变变量,用关键字var表示:
var <标识符> : <类型> = <初始化值> 注意,在kotlin中成员变量不会赋默认值,不像java一样,必须手动添加默认值。
var name : String ="yuanzhen"
name ="yuanzhen1"
var age : Int =20
age =30
println("name:$name,age:$age")
输出:
name:yuanzhen1,age:30
只能赋值一次的变量,是不可变变量,用关键字val表示,类似于java里面的final:
val <标识符> : <类型> = <初始化值> 注意,在kotlin中成员变量不会赋默认值,不像java一样,必须手动添加默认值。
1.2类型推导
kotlin可以根据传入的值,自动推导出变量类型:
var name ="yuanzhen" //类型推导
name ="yuanzhen1"
var age =20 //类型推导
age =30
1.3函数 方法
kotlin中的Unit相当于java中的void ,如果函数的返回值为Unit,可以不用写返回值
kotlin中使用fun关键字定义函数
定义一个有参数和返回值的函数:
fun test(name1:String ,name2:String):String{
return name1+name2
}
调用:
println(test("yuan","zhen"))
//输出 yuanzhen
也可以根据类型推导,直接写成:
fun test(name1:String ,name2:String) =name1+name2
可变参数用关键字vararg表示:
fun lenMethod(vararg value: Int) {
for (i in value) {
println(i)
}
}
调用:
lenMethod(1, 2, 3, 4, 5, 6, 7)
1.4字符串
在kotlin中,$表示一个变量名或者变量值,$name 表示变量值,如果变量值有多个,可以写为:${name1+name2}
var name ="yuanzhen1" //类型推导
var name1 ="yuanzhen"
println("${name+name1}")
输出:yuanzhen1yuanzhen
换行:""" """ 自己不用关心换行:
val infoMesage = """
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
""" // 前置空格
println(infoMesage)
val infoMesage2 = """
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
""".trimIndent() // 没空格
println(infoMesage2)
val infoMesage3 = """
?AAAAAAAAAAA
?BBBBBBBBBBB
?CCCCCCCCCCC
?DDDDDDDDDDD
?EEEEEEEEEEE
""".trimMargin("?") // 没空格 控制?
println(infoMesage3)
输出:
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
AAAAAAAAAAA
BBBBBBBBBBB
CCCCCCCCCCC
DDDDDDDDDDD
EEEEEEEEEEE
1.5 null检查机制
在kotlin中,如果你这么定义一个变量,一定会报错的
因为这是kotlin特有的机制,不允许直接赋空值。那么要怎么做呢?
var age:Int?=null
加个?的意思就相当于 我发出了一个广播,告诉所有人这个值可能是空的,必须要有处理措施。
第一种处理措施:
var age:Int?=null
val i = age?.and(2)
println("$i")
输出:null
age?.and(2)的意思就是如果age是null,那就不执行?后面的内容了
第二种处理措施:
var age:Int?=null
age!!.and(2)
!!的意思就是我不管,我就强行执行and方法,出了事我负责。
第三种处理措施:
就跟java一样,自己判断处理
var age:Int?=null
if(age !=null){
age.and(2)
}
1.6 区间
区间用..来表示
// 1 到 9
for (i in 1..9) {
println(i)
}
输出 1 2 3 4 5 6 7 8 9
那如果这样写呢?
for (i in 9..1) {
println(i)
}
注意:这样是不会输出的,因为没有9到1这种写法,那如果非要输出9到1呢?
for (i in 9 downTo 1) {
println(i)
}
要用downTo
还可以指定步长:
for (i in 1..20 step 2) {
println(i)
}
输出:1 3 5 7 9 11 13 15 17 19 每隔2输出一个值
排除最后一个元素:
for (i in 1 until 10) {
println(i)
}
输出:1 2 3 4 5 6 7 8 9
2, 比较与数组
2.1比较
在java中比较两个字符串,用equls来比较,但是在kotlin中,用==来比较字符串的值
val name1: String = "张三"
val name2: String = "张三"
println(name1 == name2)
比较对象地址用===表示
// --- 比较对象地址
val test1:Int? = 10000
val test2:Int? = 10000
println(test1 === test2)
输出false
2.2 数组
在java中数组有三种创建方式:
int[] array = {1,2,3};
int[] array1 = new int[3];
int[] array2 = new int[]{7,8,9};
在kotlin中 数组有两种方式:
第一种:
val numbers = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)
第二种:
val numbers2 = Array(10, {value: Int -> (value + 200) })
for (value in numbers2) {
println(value)
}
输出:
200
201
202
203
204
205
206
207
208
209
为什么会这样呢? 因为value的默认值是0,之后会依次加一。
3,条件控制
比较大小值,可以这样写:
val number1: Int = 99
val number2: Int = 88
// 表达式 比 大小 最大值
val maxValue = if (number1 > number2) number1 else number2
println(maxValue)
输出99
如果要执行多行代码,还可以这样写:
val max: Int = if (number1 > number2) {
println("number1是最大的")
number1
} else {
println("number2是最大的")
number2
}
注意:返回值不需要加return关键字
when相当于java中的switch case,只不过用法更加灵活
用于某个值:
val number5 = 5
when(number5) {
1 -> println("一")
2 -> println("二")
3 -> println("三")
4 -> println("四")
5 -> println("五")
else -> println("其他")
}
用于区间:
val number = 700
when(number) {
in 1..100 -> println("1..100")
in 200..500 -> println("200..500")
else -> println("其他")
}
用于执行多行代码 并且有返回值:
val number = 3
val result = when (number) {
1 -> {
println("很开心")
"今天是星期一"
99
}
2 -> {
println("很开心")
"今天是星期二"
88
}
3 -> {
println("很开心")
"今天是星期三"
true
100
}
else -> 99
}
4,循环与标签
4.1标签
自定义标签:在kotlin中,我们可以自定义一个标签,用来控制程序的执行流程等
yuanzhen@ for (i in 1..20) {
for (j in 1..20) {
println("i:$i, j:$j")
if (i == 5) {
// break // j循环 给break
break@yuanzhen // i循环 给break
}
}
}
一个类中自带的标签:
class Yuan {
val I = "aa"
fun show() {
println(I)
println(this.I)
println(this@Yuan.I)
}
}
4.2循环
在kotlin中,要遍历一个list,通常有三种方式:
var items = listOf<String>("aaa", "bbb", "ccc")
方式一:
for (item in items) {
println(item)
}
方式二:
items.forEach {
println(it)
}
方式三:
for (index in items.indices) {
println("下标:$index, 对应的值:${items[index]}")
}
5,类与对象
5.1类的创建
在kotlin中,创建一个类,如果前面不写修饰符,默认就是public final
// 默认就是public final
class Empty
这样是不能被继承的,要想被继承,就必须加上open
open class Person{}
5.2构造函数
在java中,会有一个默认的构造函数,并且可以重载无数个构造函数。
但是在kotlin中,它会有一个默认的主构造函数,其余的都是次构造。
上面的Person类,相当于有一个默认的主构造:
open class Person() // 主构造
{
}
那如果我们要给主构造增加一个参数呢?
open class Person(id: Int) // 主构造
{
}
那如果还要增加好几个次构造呢?
open class Person(id: Int) // 主构造
{
// 次构造
constructor(id: Int, name: String) : this(id) {
}
// 次构造
constructor(id: Int, sex: Char) : this(id) {
}
// 次构造
constructor() : this(222) {
}
}
次构造必须继承主构造,同时把参数传给主构造
在使用时,可以这么用:
val person = Person() // 次构造
val person2 = Person(23456) // 主构造
Person(234, "yy") // 次构造
Person(234, 'M') // 次构造
5.3类的继承
继承父类用:表示
class Student(id: Int) : Person(id) // 主构造
{
// 再Kotlin 全部都是没有默认值的
// 再Java 成员有默认值,但是方法内部没有默认值
// lateinit 懒加载 没有赋值 就不能使用,否则报错
lateinit var name : String
var age: Int = 0
}
5.4接口
在kotlin中,接口和抽象类默认都是open的
interface Callback {
fun callbackMethod() : Boolean
}
interface Callback2 {
fun callbackMethod() : Boolean
}
abstract class Person : Callback , Callback2 {
abstract fun getLayoutID() : Int
abstract fun initView()
}
class Student : Person() {
override fun getLayoutID(): Int = 888
override fun initView() { }
override fun callbackMethod(): Boolean = false
}
与java差别不大
5.5data数据类
数据类是kotlin中独有的,在java中,我们要写数据类,通常会手写很多属性和方法等。
在kotlin中,我们只需要用数据类定义属性就可以,不用关心get,set等方法,内部会自动帮我们生成。
// 会自动生成get set 构造 equals hashCode toString copy
data class User(val id: Int, val name: String, val sex: Char)
val user = User(99, "lisi", 'M')
//copy 函数
val(myID, myName, mySex) = user.copy()
println("myID:$myID, myName:$myName, mySex:$mySex")
5.6单例
在kotlin中,object只实例一次,相当于单例
object MyEngine {
fun m() {
println("M run")
}
fun show() {
println("我就只有一个实例")
}
}
companion :意思是同伴对象。相当于java的static.
下面来看一下kotlin中的单例模式怎么写:
方式一:
class NetManager {
// 只有一个实例
object Holder {
val instance = NetManager()
}
// 看不到 static 可以 派生操作
companion object {
// 全部都是 相当于 Java static
fun getInstance() : NetManager = Holder.instance
}
fun show(name: String) {
println("show:$name");
}
}
方式二:
class NetManager2 {
companion object {
private var instance: NetManager2? = null
// 返回值:允许你返回null
fun getInstance(): NetManager2? {
if (instance == null) {
instance = NetManager2()
}
// 如果是null,也返回回去了
return instance
// 第二种补救: 我来负责 instance 肯定不为null
// return instance!!
}
}
fun show(name: String) {
println("show:$name");
}
}
5.7嵌套类
嵌套类,就是在类的内部又写了一个类,但是它不是内部类,拿不到外部类的成员。
class Sub {
fun show() {
println()
}
class A {
class B {
class C {
}
}
}
}
5.8内部类
在kotlin中,内部类用关键字inner来表示。
class Sub {
fun show() {
println()
}
class A {
class B {
class C {
}
}
}
}
// 这个才是内部类
inner class Sub2 {
fun show() {
println(I)
}
}
}