Kotlin 基础学习

本文重要在记录基础学习知识点,以便后续再次回顾,因此也没有过多的介绍Kotlin了,目前Android studio 3.0往上就开始支持了,因此这里直接进入正题。java

变量、类型与符号

变量

Java的声明变量不用多少,相信你们都很熟悉了,那么kotlin是怎么样的呢?数组

var name: String = "Tom"//普通变量声明

val TAG: String = "MainActivity"//常量变量声明

这里只是简单的给了两个范例,var对于js的同窗应该很熟悉了,这里也是一向采用,声明的顺序是变量名在前,用:隔开 接着是类型,并且必定要初始化,不然编译器不过。app

类型

类型相比Java也是有了必定的改变,没有了Java基本数据类型,取而代之的是Int,Double,String,Boolean 等ide

符号

首先kotlin去掉了行尾标识,再也不以;为结尾,你能够写只是画蛇添足而已,编译器也不会报错。函数

:冒号的用处有不少,并且很重要,声明变量须要,并且还用于继承:oop

open class A(age: Int) {
    
}

class B(age: Int) : A(age) {
    
}

此外,若是你想在Kotlin代码中使用Java类,也须要用到“:”符号。连续两个“:”代表对Java类的调用。学习

val intent = Intent(this, MainActivity::class.java)

类型检测

Java中对于类型的检测是instanceof 便可,kotlin中采用更简单直观this

if(age is Double){

}

字符串模板

Java中使用字符串模板会比较麻烦,并且不太直观。而Kotlin里使用则异常便捷好用。spa

// Java中字符串模板两种经常使用形式
String name = "我";
int age = 25;
String.format("%s今年%d岁", name, age);
MessageFormat.format("{0}今年{1}岁", name, age);
// Kotlin中更直观的字符串模板形式
var name = "我"
var age = 25
"${name}今年${age}岁"

采用${变量名}的方式。.net

函数与方法

函数的基本声明以下:

// 普通方法定义
fun common() {
    
}

// 定义函数的参数和返回值
fun common(str: String): String {
    return TAG
}

接下来看一看函数的参数传递:

// 普通方法定义
fun common() {
    common("str","name1")
}

// 定义函数的参数和返回值
fun common(str: String,name1:String,name2:String = "jeck"): String {
    return TAG
}

咱们发现参数里能够直接用=给定默认值,这样咱们调用的时候就不用传递了。

Java中的可变参数相信你们都不会忘记,...便可,必需要在参数列最后出现

Kotlin的要求比较简单:

  • 可变参数没必要是函数的参数列表中的最后一个
  • 用vararg paramName: paramType格式申明一个可变参数
  • 和Java同样,在函数体内部,能够以数组的形式使用这个可变参数的形参变量
fun test(vararg parameterName: String, agr: Int) {
    test("", "", "", agr = 1)
}

可变参数值的话,须要用关键字vararg来定义。这里须要注意的是,一个函数仅能有一个可变参数。该可变参数不必定得是最后一个参数,但当这种状况下时,调用该方法,须要给其余未指明具体值的参数传值。

这里若是可变参数在最后一个位置的话,在以前的参数就能够直接写入参数值便可,不用=赋值

fun test(vararg parameterName: String, agr: Int) {
    addNumbers("linchunshu",1,2,3,4,5)//这里能够直接写入linchunshu 而不用name = "linchunshu"
}

fun addNumbers(name: String, vararg args: Int): Int {
    var result = 0
    for (i in args.indices) {
        result += args[i]
    }
    return result
}

这里是表明能够传递任意类型的参数,个数不限

fun main(args: Array<String>) {
    test(1,"Hello,Kotlin!",'a',User(1,"liuliqianxiao"))
}
//用Any表明任意类型
fun test(vararg args: Any){
    for(it in args){
        println(it)
    }
}
class User(var id: Int,var name: String){
    override fun toString(): String {
        return "User(id=$id, name='$name')"
    }
}

类与继承

Kotlin中也使用class关键字定义类,全部类都继承于Any类,相似于Java中Object类的概念。类实例化的形式也与Java同样,可是去掉了new关键字。

构造函数

Kotlin的构造函数分为主构造器(primary constructor)和次级构造器(secondary constructor)。下面咱们来看看他们的写法。

primary constructor:

open class A(username: String, age: Int) {
    var username: String
    var age: Int

    init {
        this.username = username
        this.age = age
    }
}

init关键字在class里面做用是使参数进行初始化,初始化代码须要单独写在init代码块中。

这里须要注意几点:

关键字constructor:在Java中,构造方法名须和类名相同;而在Kotlin中,是经过constructor关键字来标明的,且对于Primary Constructor而言,它的位置是在类的首部(class header)而不是在类体中(class body)。

关键字init:init{}它被称做是初始化代码块(Initializer Block),它的做用是为了Primary Constructor服务的,因为Primary Constructor是放置在类的首部,是不能包含任何初始化执行语句的,这是语法规定的,那么这个时候就有了init的用武之地,咱们能够把初始化执行语句放置在此处,为属性进行赋值。

固然上面初始化咱们也能够在变量声明直接进行初始化:

open class A(username: String, age: Int) {
    var username: String = username
    var age: Int = age

}

能够看出,咱们的写法二实际上就是对咱们在写法一前面提到的两个关键字的简化。

当咱们定义一个类时,咱们若是没有为其显式提供Primary Constructor,Kotlin编译器会默认为其生成一个无参主构造,这点和Java是同样的。好比有这样的一个类:

class Person {
    private val username = "David"
    private var age = 23

    fun printInfo() {
        println("username = $username, age = $age")
    }
}
fun test(args: Array<String>) {
    val person = Person()
    person.printInfo()
}

Secondary Constructor:

和Primary Constructor相比,很明显的一点,Secondary Constructor是定义在类体中。第二,Secondary Constructor能够有多个,而Primary Constructor只会有一个。

open class C(username: String, age: Int) {
    var username: String
    var age: Int
    var sex: String
    var isMarried: Boolean

    init {
        this.age = age
        this.username = username
        this.sex = "男"
        this.isMarried = false
    }

    constructor(username: String, age: Int, sex: String) : this(username, age) {
        this.sex = sex
    }

    constructor(username: String, age: Int, sex: String, isMarried: Boolean) : this(username, age, sex) {
        this.isMarried = isMarried
    }
}

咱们看上面的例子,首先主构造函数包含了两个参数,次级构造函数咱们设置了两个,而且参数依次多一个,咱们很感兴趣的就是this(),这里咱们是在次级构造函数里面调用主构造函数,咱们发现四个参数的调用三个参数的,三个参数的调用主构造函数,这也说明了,次级构造函数直接或者间接的调用了主构造函数,而且若是咱们不调用就会报错。

继承

类的继承使用符号“:”表示,接口的实现也同样。kotlin和Java在这里有一个很明显的区别就是咱们定义一个类的时候,咱们不能随意的继承某个类,换句话说若是某个类想要被继承那就必须得声明为open,上面的例子中的代码也有写道,kotlin取消了final这个关键字,因此默认都是不可继承的。

伴随对象

Kotlin 取消了关键字static,也就没法直接声明静态成员,因此引入了伴生对象这个概念,能够理解为“影子”

  • 伴生对象之于它所在的类是“如影随形”
  • 使用关键字companion表示伴随,object表示对象
    实例:

其实跟Java的static静态代码块很相似:

class B(name: String, age: Int) : A(name, age) {

    companion object haha{
        fun sys(){
            println("haha")
        }
    }
}
B.sys()

声明和使用其实很简单,至关于静态方法调用的过程,这里的haha能够不用写,咱们能够直接声明伴随对象。

再详细的伴随对象知识后面我会写一篇博客。

逻辑语句

接下来是咱们常常用到的一些逻辑语句,使用上会有所变化。

if-else语句没有改变,该怎么用仍是怎么用。

if-else语句能够做为一个逻辑表达式使用

var age:Int = if(x > y) x else y

这是kotlin的特色,还能够做为代码块出现:

var age1: Int = if (x > y) {
    print("x")
    x
} else {
    print("y")
    y
}

咱们能够作不少事代码块里面。

when

这个用起来也是比较简单:

fun t(x: Int):String {
    when (x){
        1 -> return "1"
        2 -> return "2"
        3 -> return "3"
        else -> return "-1"
    }
}

标签

Kotlin中能够对任意表达式进行标签标记,形式为abc@,xyz@。而这些标签,能够搭配return、break、continue等跳转行为来使用。

fun returnDemo2() {
    println("START : " + ::returnDemo2.name)
    val intArray = intArrayOf(1, 2, 3, 4, 5, 6, 7)
    intArray.forEach here@{
        if (it == 3) return@here//指令跳转到lambda表达式标签here@处。
        println(it)          //继续下一个it = 4遍历循环
    }
    println(" END : " + ::returnDemo2.name)//结果一、二、四、五、六、7
}
fun main(args: Array<String>) {
    loop@ for (i in 1..4) {
        for (j in 1..4) {
            if (i == 2 && j == 2) {
                break@loop
            }
            println("i = $i, j = $j")
        }
    }
}

这样能够直接跳出外层循环

跟java相似:

public void t() {
    loop:
    for (int i = 1; i <= 4; i++) {
        for (int j = 1; j <= 4; j++) {
            if (i == 2 && j == 2) {
                break loop;
            }
            System.out.println("i = " + i + ", j = " + j);
        }
    }
}

在外层循环处声明一个标签loop@,当须要 break 的时候,直接使用break@loop就能够跳出外层循环。

fun main(args: Array<String>) {
    val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

上面代码输出为:123,在0时直接返回不会继续打印。

val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach lit@ {
    if (it == 0) return@lit
    print(it)
}

这里加上标签就会直接过滤掉0,打印位:123456

上面方式还能够写成隐藏标签:

val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach {
    if (it == 0) return@forEach
    print(it)
}

直接返回标签forEach便可。

for

fun mainList(args: Array<String>) {
    val items = listOf("apple", "banana", "kiwi")
    for (item in items) {
        println(item)
    }

    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

其余的就跟Java都同样啦!

基础知识大概就这么多,后面还会详细的记录个别的深刻使用方法!

相关文章
相关标签/搜索