美文网首页
Kotlin基础写法总结

Kotlin基础写法总结

作者: d41f12d62517 | 来源:发表于2019-11-24 15:26 被阅读0次

    总结一下基础的写法,方便自己快速的回顾。

    一、 变量

    在 Kotlin 中所有的变量都是不允许为 null 的。

    空安全设计

    但是实际场景是需要一些变量在声明的时候初始值是 null。可以如下声明:

    class User{
      var name : String? = null
    }
    

    Kotlin中专业术语:可空类型 。
    可空类型变量调用之后会导致空指针异常,编译器会不通过编译。两种避免这种情况的写法:

      //第一种写法, 编译器会做一次非空确认, safe call
      var view? = null
      view?.setBackgroundColor(Color.RED)
    
      //第二种写法,坚定变量绝对不为空,实际效果就和 Java 的一样
      view !!.setBackgroundColor()
    

    延迟初始化

    顾名思义,直接看如何写:

    lateinit var view: View
    override fun onCreate(...) {
        view = findViewById(...)
    }
    

    类型推断

    做为静态语言的Kotlin,可以在写变量的时候不用写变量类型。

    var name = "qhh"
    

    val 和 var

    var :可读写变量
    val :只读变量,只能赋值一次。

    二、函数

    函数声明

    fun getAddress(name : String): String{
    } 
    

    无返回值的写法:

    fun setAddr(): Unit {}
    //或者省略 Unit
    fun setAddr(): {}
    

    函数参数的注意点。参考抛物线的总结

    // 👇可空变量传给不可空参数,报错
    var myName : String? = "rengwuxian"
    fun cook(name: String) : Food {}
    cook(myName)
      
    // 👇可空变量传给可空参数,正常运行
    var myName : String? = "rengwuxian"
    fun cook(name: String?) : Food {}
    cook(myName)
    ​
    // 👇不可空变量传给不可空参数,正常运行
    var myName : String = "rengwuxian"
    fun cook(name: String) : Food {}
    cook(myName)
    

    getter / setter 函数

    var name = "qhh"
          get(){
              return field + " 666"
          }
          set(value){
              field = " we " + value
          }
    
    val name = "qhh"
          get(){
              return field + " 666"
          }
    

    field 相当于每个 var 中的内部变量

    三、 类型

    基本类型

    Kotlin中基本类型和Java的相差不多。但是也是有区别的地方。
    1、Int类型装箱
    Kotlin装箱时根据场景来决定。

    var a: Int = 1 // unbox
    var b: Int? = 2 // box
    var list: List<Int> = listOf(1, 2) // box
    

    装箱的过程是耗费性能的,所以尽可能的使用不可空变量。

    2、数组的写法区别
    Kotlin中数组的写法:(不装箱)

    var array: IntArray = intArrayOf(1, 2)
    

    使用不可空变量和IntArray等数组类型,都是不装箱的

    四、类和对象

    类的构造函数

    1、主构造函数
    主构造函数的书写方式一:

    class Student constructor(name: String)
    

    constructor 可以省略,但是在有可见性修饰符修饰以及注解则不可以省略。
    主构造函数中的参数,可以在 init 函数块中进行相关业务逻辑。

    class Student constructor( name: String){
        
        val TAG = "Student"
        
        init {
            Log.d(TAG,"name is $name")    
        }
        
    }
    

    2、次构造函数

    class Person {
    
        var firstName: String
        
        constructor(name: String){
            firstName = name
        }
        
    }
    

    3、构造函数的委托机制
    通过 this 实现,有点类似 Java 中的 super

    class Student constructor( name: String){
    
        var studentName = name
        var studentAge: Int = 0
    
        init {
            Log.d("qhh","name is $name")
        }
        
        constructor(age: Int,name: String) : this(name) {
            studentAge = age
        }
    
    }
    

    初始化代码块,是主构造函数的一部分,都会在次构造函数之前执行,不管有没有主构造函数都是如此。

    类的继承以及接口的实现方式

    interface Impl {}
    
    class MainActivity : AppCompatActivity(), Impl {}
    

    Kotlin中类默认都是 final 的,不可继承的。只有添加了 open 的类,子类才可以继承它。

    open class Parent {
        
        lateinit var mName: String
        
        open fun setName(name: String): Unit {
            println("setName = $name")
            mName = name
        }
    
        fun work(): Unit {
            
        }
    }
    

    子类中覆盖父类的方法必须使用 override 。

    class Children : Parent() {
    
        override fun setName(name: String) {
            super.setName(name)
            println("children name is $name")
        }
    
    }
    

    抽象 abstract 关键字,在Kotlin中同样的保留。

    abstract class Base {
        
        abstract fun base() : Unit
        
    }
    

    同样,在 abstract 类中也可以没有 abstract 函数。

    最终创建类的实例

    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val student = Student("小明")
    
            val person = Person("老刘")
    
            val parent = Parent()
            parent.setName("大明")
            parent.work()
    
            val children = Children()
            children.setName("小黄")
    
            val derive = Derive()
            derive.base()
        }
    }
    

    类型转化

    同Java一样,子类在实例的时候是可以赋值给父类变量,反过来则不行。

    var parentNew: Parent = Children()
    

    多态的特性同样保存,并且转为父类之后,同样是无法调用子类中的方法。这个就涉及到类型的强转。Kotlin中使用到的是 is 和 as 两个操作符。

    if(parentNew is Children){
                parentNew.childWork("work 1")
            }
    
            (parentNew as Children).childWork("work 1")
    

    as 配合 ?同时使用,可以处理判断类型转换的安全问题。

    //表示 parentNew 是Children 类的父类或者是Children类,则执行childWork,如果不是则不执行
    (parentNew as? Children)?.childWork("11")
    

    注意: parentNew as? Children 之后是一个可空类型的对象

    总结

    在学习了之后大致的一个基础使用的总结。学习过程中在看的是 Kotlin的官网教程,以及 抛物线的网站。

    参考:
    https://www.kotlincn.net/
    https://kaixue.io/kotlin-basic-1/?utm_source=androidweekly.io&utm_medium=website

    相关文章

      网友评论

          本文标题:Kotlin基础写法总结

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