Kotlin 基础篇一

Kotlin运行原理

java虚拟机并不是和编写的java代码打交道,而是处理编译之后的class文件

Kotlin使用了新的编译规则生成class文件,只要class文件的符合规范java虚拟机就可以识别。

Kotlin的优势

1.Kotlin语法更加简洁,代码量可能会减少50%

2.Kotlin增加了很多高级语法特性,使得开发效率大大提升

3.Kotlin在语言安全性上方面下了很多功夫,几乎杜绝了空指针这个崩溃率最高的异常。

4.Kotlin和java 100%兼容,可以无缝只用java的三方库

var 与 val

var表示可变的变量 variable的简写

val 表示不可变的变量相当于final value的简写

使用这种定义变量的方式,那么编译器是怎么知道类型的这个得益于kotlin具有出色的类型推到机制

==优先使用val 声明变量,当这个不能满足的时候再使用var==

定义函数的方式

fun add(a:Int,b:Int):Int{
    return a+b;
}

add是函数名,括号里边的是参数,格式是:参数名:参数类型,如果不需要输入参数可以是一个空括号。

括号后边的是是返回值的类型,没有就不用写。语句的后边不需要添加分号

Kotlin的内置函数

fun largeNumber(a:Int,b: Int):Int{
    return max(a,b)
}

max就是kotlin的内置函数

Kotlin语法糖

当一个函数只有一行代码的时,Kotlin允许我们不必写函数体,可以直接将唯一的一行代码写在函数定义的尾部,中间使用等号连接即可,如上边的函数可以使用这个方式进行编写。

fun largeNumber(a:Int,b:Int):Int= max(a,b)

条件语句有两种实现方式:if和when。

if条件语句

Kotlin的if和java几乎是没有区别的,不同之处在于kotlin中的if多了一个额外的功能:可以有返回值的,返回值就是if语句每一条件的最后一行代码的返回值,如下面这个写法

fun largeNumber(a:Int,b:Int):Int{
    return if (a>b){
        a
    }else{
        b
    }
}

根据语法糖可以进一步精简

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

这个就是kotlin 代码简洁的例子

when条件语句

when语句有点类似于java中的switch语句,但是比switch语句强大。

fun getScore(name:String) = when(name){
    "tom"->84
    "lili"->82
    "jack"->85
    "tong"->86
     else->0
}

省去了if判断,简洁清爽。

when语句还支持类型判断

fun checkType(num:Number):String{
    return when (num) {
        is Int -> "is int"
        is Double -> "is double"
        else -> "error type"
    }
}

类型判断代码中,is关键字就是类型匹配的核心,它相当于java 的instanceof关键字。Number 是kotlin内置的一个抽象类,Int、Long、Float、Double都是它的子类。

kotlin中判断字符串或者对象是否相等可以直接使用==,不用调用equals()方法。

循环语句

kotlin中跟java一样也提供了两种循环语句:while和for循环,while和java的完全一样。

其中对for循环做了很大幅度的修改,java中使用的for-i 循环在kotlin中别舍弃了,for-each被加强变成了for-in循环

kotlin 表示一个区间

val range=0..10;  //[0,10]

这个表示方式,两端都会包含

val range=0..10;  //[0,10]
for (i in range){
    println("i=$i");
}

上面的方式在当成数组的下标的时候不方便,因为最后一个数字是不包含的,可以采用这个方式

val range=0 until 10;  //[0,10)  这个是左闭右开的

这样就不包含最后的10了

for (i in range step 2){
    println("i=$i");
}

step 这个可以在循环的时候跳过某些元素

如果想创建一个降序的空间

val down=10 downTo 1  //[10,1]

Kotlin 面向对象

下面创建一个类

class Person {
    var name=""
    var age=0

    fun eat(){
        println(name+"is eating. he is "+age+"years old.")
    }
}

//实例化调用这个类
fun main(){
    val p=Person();  //声明一个对象
    p.name="tom"
    p.age=10
    p.eat()
}

kotlin本着最简化的设计原则,把new关键字和分号都省了

面向对象的一个重要的特性-继承

open class Person {
    var name=""
    var age=0

    fun eat(){
        println(name+"is eating. he is "+age+"years old.")
    }
}

class Student : Person() { //
    var studentNumber = 0   //学号
    var grade=0     //年级

}

上面写了一个Student 类继承Person类,继承只需要使用:就可以,不用再使用extends 关键字。

注意:Person类的声明变化,类前面加了一个open的关键字,如果不加这个关键字是不能被继承的。

在kotlin中所有的非抽象的类默认都是不允许被继承的,相当于java中给类加了一个final关键字。

继承本身带有侵入性,按照依赖倒置的原则,高层模块不应该继承底层模块都应该继承抽象的语义,好多时候java中没有这个语法限制,常常会违背这个设计原则。如果一个类不是专门为继承设计的,那么就应该主动加上final关键字,禁止它被继承。

这里还有一个点,就是父类后边的括号,为什么需要加括号?这里就涉及到kotlin中 主构造函数、次构造函数等方面的内容。

主构造函数将会是最常用的构造函数,每个类都会有一个默认的无参主构造函数,主构造函数的特点是没有函数体,直接定义在函数的后边。

class Student( val studentNumber:Int, val grade:Int) : Person() { 
    init {
        println("studentNumber is $studentNumber")
        println("grade is $grade")
    }
}

上面这个写法就相当于声明了主构造函数的带两个参数的,kotlin还提供了init结构体,所有主构造函数的逻辑可以写在里面。

这些跟父类的括号有什么关系呢,这就涉及java 继承特性的一个规定,子类的构造函数必须调用父类的构造函数。可是主构造函数并没有函数体,就没办法调用父类的构造函数了。有一个方法就可以放在init方法,好多情况下是不需要写init结构体的。

所以这里的括号就是子类主构造函数调用父类的那个构造函数,在继承的时候使用括号来指定。

次构造函数一般用不到,次构造函数跟主构造函数的区别是:次构造函数有函数体。

kotlin规定,当一个类既有主构造函数,也有次构造函数的时候,次构造函数必须调用柱构造函数。

次构造函数使用constructor进行定义。

class Student( var studentNumber:Int, var grade:Int) : Person() {
    //这个结构体,专门用于构造函数的调用
    init {
        println("studentNumber is $studentNumber")
        println("grade is $grade")
    }
    //这个是次构造函数
    constructor(studentNumber:Int):this(studentNumber,0)
    //这个是次构造函数
    constructor():this(0)

}

另外kotlin还允许自由次构造函数,没住构造函数的情况,这个情况父类的括号可以省了,由于没有主构造函数,次构造函数只能直接调用父类的构造函数

class Student : Person {
    //这个是次构造函数
    constructor(studentNumber:Int):super(){
        println("studentNumber is $studentNumber")
    }
}

kotlin中的接口

java中可以是单继承,可以有多个实现。kotlin也是这样的。

open class Person(name:String, age:Int) {
    var name=name
    var age=age

    fun eat(){
        println(name+"is eating. he is "+age+"years old.")
    }
}

class Student( name:String, age:Int) : Person(name,age),Study {
    override fun readBooks() {
        println("$name is read books")
    }
}

kotlin中实现一个接口,不再使用implements 这个关键字,统一使用冒号和逗号。

使用override关键字来重写父类或者接口中的函数。

另外kotlin还允许接口中定义默认实现,拥有了默认实现就不要求实现类必须重写这个方法了,可以选择重写。

kotlin类的可见性

修饰符 java kotlin
public 所有类可见 所有类可见(默认)
private 当前类可见 当前类可见
protected 当前类、子类,同一个包下的可见 当前类、子类
default 同一包下面的类可见(默认)
internal 同一个模块的类可见

internal是kotlin新增的一个关键字,这个是同一个模块中的类可见,应用场景:当我们开发一个模块给别人使用,有一些类只想内部调用,不想外部调用就可以使用这个关键字进行函数声明。

kotlin的数据类

java 声明一个数据实体类

public class CellPhone {
    
    String brand;
    
    double price;

    public CellPhone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
       if (o instanceof CellPhone){
           CellPhone other= (CellPhone) o;
           return other.brand.equals(brand)&&other.price==price;
       }
       return false;
    }

    @Override
    public int hashCode() {
        return (int) (brand.hashCode()+price);
    }

    @Override
    public String toString() {
        return "CellPhone{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

重写了equals 和hashCode方法,有的时候不重写,当使用hashMap和hashCode的时候会有问题,toString是为了打印日志。

kotlin声明一个数据实体类

data class CellPhone(val brand:String, val price:Double)

一行搞定了,不管是打印数据还是使用HashMap和HashCode 都不会有问题。就是因为使用data关键字,就表明希望这个类是一个数据类,kotlin就把equals、hashCode、toString这些方法自动生成了,从而简化开发工作量。当类中没有别的实现,大括号也可以省略。

kotlin中的单例设计模式

java中的单例有饱汉式、饿汉式、双检测、匿名内部类、枚举等实现方式。

下面看kotlin的单例实现方式

object SingleTon {

    fun test(){
        println("单例测试")
    }
}

只需要将class关键字改成object ,使用这个关键字kotlin就会帮我们创建一个SingleTon的实例,并保证全局只有一份实例。

上面分享的这些内容,学习郭霖的书籍总结而来,希望能给初学者带来帮助,共同进步,共同成长。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容