Kotlin 基础学习

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

变量、类型与符号

变量

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

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

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

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

类型

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

符号

首先kotlin去掉了行尾标识,不再以;为结尾,你可以写只是多此一举而已,编译器也不会报错。

:冒号的用处有很多,而且很重要,声明变量需要,而且还用于继承:

open class A(age: Int) {
    
}

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

此外,如果你想在Kotlin代码中使用Java类,也需要用到“:”符号。连续两个“:”表明对Java类的调用。

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

类型检测

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

if(age is Double){

}

字符串模板

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

// 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}岁"

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

函数与方法

函数的基本声明如下:

// 普通方法定义
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)//结果1、2、4、5、6、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都一样啦!

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3761034/blog/3050018

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值