Kotlin基础一

558 阅读5分钟

内容

  • 函数、变量、类、属性以及枚举
  •  Kotlin 中的控制结构 
  • 智能转换

一  函数声明

fun max(a: Int, b: Int): Int {

    return if (a > b) a else b
}

      函数的声明以关键字 fun 开始,函数名称紧随其后:这个例子中函数名称是 max ,接下来是括号括起来的参数列表。参数列表的后面跟着返回类型,他们之间用冒号隔开。假如没有返回值可以直接不写或者写成Unit类型。

注意:这里return后边代码是表达式而不是语句,表达式有返回值,语句没有返回值。而再Kotlin中基本,除了循环( for, do do/while )以外大多数控制结构都是表达式。

上边函数还可以这样写:

fun max(a: Int, b: Int): Int = if (a > b) a else b

如果函数体写在花括号中,我们说这个函数有代码块体。如果它直接返回了个表达式,它就有表达式体

还可以这样写:

fun max(a: Int, b: Int) = if (a > b) a else b

因为Kotlin有类型自动推导特性。

注意:只有表达式体函数的返回类型可以省略。对于有返回值的代码块体函数, 必须显式地写出返回类型和 return 语句。

二 常量和变量

在 Kotlin中以关键字开始,然后是变量名称, 最后可以加上类型(不加也可以)。声明变量的关键字有两个

  •  val (使用 val 声明的变量不能在初始化之 后再次赋值。它对应的是 Java final 量。) 
  •  var (这种变量的值可以被改变。这种声明对 应的是普通(非 final )的 Java 量。)

如下:

fun ddd() {
    //隐式声明局部常量,类型自动推导
    val a = 1
    //显示声明局部变量
    var b: Int = 2
    //如果不能提供可以赋给这个常量的值的信息,编译器就无法推断出它的类型,并且val只有一次赋值机会
    val c: String
    c = "Kotlin就是厉害"
}

注意 val 引用自身是不可变的,但是它指向的对象可能是可变的。如下代码完全有效

val array= arrayListOf<String>("1","2","3")
array.add("4")

不可变对象和可变对象我们之后再讨论。

注意:编译器只会根据初始化器来推断变量的类型,在决定类型的时候不会考虑 后续的赋值操作。如下错误的写法:

var b: Int = 2
b = "类型错误"

三 类

 java中的类:

public class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

使用Kotlin就变成了:

class Person(val name: String)

注意:从 Java otlin 的转换过程中 public 修饰符消失了 。在 Kotlin 中, public 是默认的可见性,所以你能省略它。

四 属性

4.1 属性声明和使用

       在类中声明一个属性和声明一个变量一样:使用val和var关键字。声明成val的属性是只读的,而var属性是可变的。当你声明属性的时候,你就声明了对应的get和set方法(只读属性有一个get,而可写属性既有get也有set)如:

class Person {
    var name: String = "张三"
    val isMan: Boolean = false
}

当你使用这个类的属性时候,内部其实是调用的对应的get和set方法,而是未呈现出来

var p = Person()
//设置值,内部其实是调用了set,只是未呈现
p.name = "张三"
//获取值,内部其实是调用了get,只是未呈现
Log.e("rrrrr",p.name)

如果我们去呈现他的get和set方法的就像这样:

class Person {
    var name: String = "张三"
    get(){
        return field
    }
    set(value) {
        field = value
    }
    
    val isMan: Boolean = false
        get(){
            return field
        }

}

注意:需要解释的是这个field ,你可以把field认为就是name,也可以把field认为是isMan,它的出现就是为了解决死循环,因为默认使用属性,就是调用属性的get方法。

4.2 自定义get和set方法

如创建一个长方形类,里边有一个字段,是判断长方形是否是正方形的标记,我们可以这样写:

class Rect(var w :Int ,var h:Int) {
    val isSQ :Boolean
    get() {
        return w==h
    }
}

调用:

var rect = Rect(10,10)
Log.e("rrrrrrr","${rect.isSQ}")

Log如下:

rrrrrrr: true                                                                                

4.3 修改属性的可见性

我们可以在自定义的get或者set方法前边加上可见修饰符去修改属性的可见性,访问器的可见性默认与属性的可见性相同。

五 枚举

      Kotlin中使用了两个关键字去声明枚举,enum 和 class, enum是一个所谓的软关键字:只有当它出现在class前面时才有特殊的意义,在其他地方可以把它当作普通的名称使用。

enum class Colors() {
    //创建枚举对象
    Red(),Blue(),Black();

}

六 控制语句

6.1 when

when好比java中的switch,比switch强大之处,它也是一个表达式,有返回值,不仅可以传递常量,还可以传递对象。通过上边枚举去选择性返回一个数字,代码如下:

6.1.1传递常量

private fun select(color: Colors): Int {
    return when (color) {
        Colors.Blue->0 
        Colors.Black -> 1
        Colors.Red -> 2
    }
}

调用这个方法,传递的参数不同,获取到的返回值也是不同的。上边代码还可以写成这样:

fun select(color: Colors) = when (color) {Colors.Blue->0 ;Colors.Black -> 1 ;Colors.Red -> 2 }

6.1.2 传递对象

假设我们有这样一个需求,用代码创建一个调色板,传递一个俩个颜色的set集合对象,返回一个他们的综合色,代码如下:

fun palette(color1: Color, color2: Color): String {
    return when (setOf(color1, color2)) {
        setOf(Color.Red, Color.Black) -> "蓝色"
        setOf(Color.Red, Color.Blue) -> "绿色"
        else -> "未知颜色"
    }

}

注意:

set集合这样写他们是相等的:

val set1 = setOf("1","22")
val set2 = setOf("22","1")

但是这样写他们就是不相等

val set1 = HashSet<String>()
set1.add("1")
set1.add("22")
val set2 = HashSet<String>()
set1.add("22")
set1.add("1")

在java中更是需要自己去循环比较是否相等。


而list集合不管怎么样去创建都是相等的:

var arr1 = ArrayList<String>()
arr1.add("11")
arr1.add("22")
var arr2 = ArrayList<String>()
arr2.add("11")
arr2.add("22")

var arr3  = listOf("11","22")
var arr4  = listOf("11","22")

在java中用equals方法判断里边值是否相等

关于更多的集合的比较在后边在去详细说明,这里先记下有这个情况!!!

6.2 if

6.2.1基本用法

上文已经简单的使用了,if的基本用法:

fun max(a: Int, b: Int) = if (a > b) a else b

这个表达式体和三元运算符长的很像,因为在Kotlin中if是表达式有返回值 ,所以在Kotlin中没有三元运算符的语法。

     在java中类型转换需使用instanceOf , 之后再去向下转型。在kotlin中使用关键字is 判断后,类型会自定转换成你要转换的类型方法。

这里我们去创建一个父亲接口,还有两个儿子类有各种独有的方法:

interface Father

class Son1:Father{ fun  son1Method(){} }

class Son2:Father{ fun  son2Method(){} }

判断是哪个儿子的方法:

fun who(aaa: Father) {
  if (aaa is Son1){
      aaa.son1Method()//这里判断是儿子1,只能调用儿子1的方法
  }else if (aaa is Son2){
      aaa.son2Method()//这里是儿子2,只能调用儿子2的方法
  }
}

 如果想要显示的转换类型就需要使用 as关键字。

6.2.2 if和when之间转换

上边代码判断是哪个儿子的方法,用when重构代码如下:

fun who(aaa: Father) {

    when (aaa){
         is Son1->aaa.son1Method()
         is Son2->aaa.son2Method()
    }

}

这里更加说明when的强大之处,可以传递常量,对象,甚至是类型判断

6.3 while

Kotlin并没有给这些简单的循环带来任何新东西,和java一样,不作为探讨内容。

6.4 for

6.4.1基础

for循环仅以唯一一种形式存在,和Java的for-each循环一致。Kotlin使用了区间的概念,区间本质上就是两个值之间的间隔,这两个值通常是数字:一个起始值,一个结束值,且起始值必须小于结束值。使用..运算符来表示区间:val oneToTen = 1..10,默认总是前后都是闭合区间
for (a in 1..100){
    
}

起始值大于结束值用downTo:

for (a in 100 downTo 1){
  
}

每隔两步一循环

for (a in 1..100 step 2 ){

}

for (a in 100 downTo 1 step 2){

}

step传递的是绝对值,和正序倒序无关,它会自动判断是每加两步还是每减两步

如果循环区间想写成前闭后开,你可以这样:

for (a in 1 until 100){
}

小结:for循环必须使用关键字in ,至于区间可以在 .. 或者downTo 或者until之间最少选择一个,step表示步长,和正负无关。

6.4.2循环map

循环map还是和java中有区别的,在java中循环map需要去通过键获取值,而在kotlin中你可以一次全部循环处理,代码可以这样写:

val map = TreeMap<String,String>()
 map.put("1","1.1")
 for ((key,value) in map) {
     Log.e("rrrr","key${key}===value${value}")
 }

这使你更加容易去取到map中的值。

6.4.3循环arraylist:

val arr = arrayListOf("1","2")
//正常循环和java并无异样
 for (value in arr){  
     Log.e("rrr","value${value}")
 }
  //使用withIndex 循环,是循环带有下边的list集合
 for ((index ,value) in arr.withIndex()){
     Log.e("rrr","value${value}index${index}")
 }

6.4.4 in关键字能用到哪些控制结构中

上边循环for中使用了in。同时在if中也能用in使用in运算符来检查一个值是否在区间中,或者它的逆运算,!n,来检查这个值是否不在区间中。

val arr = arrayListOf("1","2")
if ("1" !in arr){
}

而且在when中也能使用in,代码和使用is是一样的。

小结:

  • 方法声明的结构,以及表达式体和代码块体。
  • 常量和比变量的声明,数组不变,数组里内容可变
  • 类型自动推导的便捷使用。
  • 类的声明,以及关键字class 
  • 属性的声明以及重写get和set方法
  • 枚举的声明格式,软关键字menu
  • when控制结构,可以传递常量对象,甚至可以使用is或者in关键字
  • if控制结构,使用关键字is ,in, .. , downTo ,step ,until
  • for控制结果,使用关键字 in, .. , downTo ,step ,until,循环map和循环带下表的arraylist集合