美文网首页
Kotlin 基础篇一

Kotlin 基础篇一

作者: 何以邀微微 | 来源:发表于2022-01-04 19:39 被阅读0次

    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的实例,并保证全局只有一份实例。

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

    相关文章

      网友评论

          本文标题:Kotlin 基础篇一

          本文链接:https://www.haomeiwen.com/subject/dyhccrtx.html