美文网首页
Kotlin 的变量、函数和类型

Kotlin 的变量、函数和类型

作者: 吐必南波丸 | 来源:发表于2019-12-16 20:50 被阅读0次

    变量

    变量声明:var 、val 、lateinit

    • 类型和变量名位置互换了
    • 中间是用冒号分隔的
    • 结尾没有分号(对,Kotlin 里面不需要分号)
    var name: String? =null
    这种类型之后加 ? 的写法,在 Kotlin 里叫可空类型
    
    • val 只读变量
      • 只能复制一次,不能修改 类似java中的final
    • lateinit 延迟初始化
      • 意思是:告诉编译器我没法第一时间就初始化,但我肯定会在使用它之前完成初始化的。
        lateinit var textView: TextView
        var name:String =null
    类似java中的final
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_first)
            textView = findViewById(R.id.tv_textView)
        }
    

    类型推断

    Kotlin 有个很方便的地方是,如果你在声明的时候就赋值,那不写变量类型也行:

    🏝️
    var name: String = "Mike"
    👇
    var name = "Mike"
    

    函数

    Kotlin 除了变量声明外,函数的声明方式也和 Java 的方法不一样。Java 的方法(method)在 Kotlin 里叫函数(function),其实没啥区别,或者说其中的区别我们可以忽略掉。对任何编程语言来讲,变量就是用来存储数据,而函数就是用来处理数据。

    函数的声明

    java
    Food cook(String name) {
        ...
    }
    
    🏝️kotlin
    👇                      👇
    fun cook(name: String): Food {
        ...
    }
    
    • 以 fun 关键字开头
    • 返回值写在了函数和参数后面

    基本类型

    • 在 Kotlin 中,所有东西都是对象,Kotlin 中使用的基本类型有:数字、字符、布尔值、数组与字符串。
    🏝️
    var number: Int = 1 // 👈还有 Double Float Long Short Byte 都类似
    var c: Char = 'c'
    var b: Boolean = true
    var array: IntArray = intArrayOf(1, 2) // 👈类似的还有 FloatArray DoubleArray CharArray 等,intArrayOf 是 Kotlin 的 built-in 函数
    var str: String = "string"
    

    类和对象

    • 首先是类的可见性,Java 中的 public 在 Kotlin 中可以省略,Kotlin 的类默认是 public 的。
    • 类的继承的写法,Java 里用的是 extends,而在 Kotlin 里使用 :,但其实 : 不仅可以表示继承,还可以表示 Java 中的 implement。
      • 举个例子,假设我们有一个 interface 叫 Impl:
    🏝️
    interface Impl {}
    
    ☕️java
    public class Main2Activity extends AppCompatActivity implements Impl { }
    
    🏝️kotlin
    class MainActivity : AppCompatActivity(), Impl {}
    
    • 构造方法的写法不同。
    ☕️ java
    public class MainActivity extends AppCompatActivity {
        // 👇默认构造函数
        public MainActivity() {
        }
    }
    
    🏝️ kotlin              
    class MainActivity constructor() : AppCompatActivity() {
                            👆
    }
    
    • override 的不同
      • Java 里面 @Override 是注解的形式。
      • Kotlin 里的 override 变成了关键字。
      • Kotlin 省略了 protected 关键字,也就是说,Kotlin 里的 override 函数的可见性是继承自父类的。
        除了以上这些明显的不同之外,还有一些不同点从上面的代码里看不出来,但当你写一个类去继承 MainActivity 时就会发现:
    • Kotlin 里的 MainActivity 无法继承:
    🏝️
    // 👇写法会报错,This type is final, so it cannot be inherited from
    class NewActivity: MainActivity() {
    }
    
    - 原因是 Kotlin 里的类默认是 final 的,而 Java 里只有加了 final 关键字的类才是 final 的。
    

    那么有什么办法解除 final 限制么?我们可以使用 open 来做这件事:

      🏝️
    open class MainActivity : AppCompatActivity() {}
    

    这样一来,我们就可以继承了。

    🏝️
    class NewActivity: MainActivity() {}
    

    类型的判断和强转

    • 刚才讲的实例化的例子中,我们实际上是把子类对象赋值给父类的变量,这个概念在 Java 里叫多态,Kotlin 也有这个特性,但在实际工作中我们很可能会遇到需要使用子类才有的函数。
      比如我们先在子类中定义一个函数:
    🏝️
    class NewActivity : MainActivity() {
        fun action() {}
    }
    

    那么接下来这么写是无法调用该函数的:

    🏝️
    fun main() {
        var activity: Activity = NewActivity()
        // 👆activity 是无法调用 NewActivity 的 action 方法的
    }
    

    在 Java 里,需要先使用 instanceof 关键字判断类型,再通过强转来调用:

    void main() {
        Activity activity = new NewActivity();
        if (activity instanceof NewActivity) {
            ((NewActivity) activity).action();
        }
    }
    

    Kotlin 里同样有类似解决方案,使用 is 关键字进行「类型判断」,并且因为编译器能够进行类型推断,可以帮助我们省略强转的写法:

    🏝️
    fun main() {
        var activity: Activity = NewActivity()
        if (activity is NewActivity) {
            // 👇的强转由于类型推断被省略了
            activity.action()
        }
    }
    

    那么能不能不进行类型判断,直接进行强转调用呢?可以使用 as 关键字:

    🏝️
    fun main() {
        var activity: Activity = NewActivity()
        (activity as NewActivity).action()
    }
    

    这种写法如果强转类型操作是正确的当然没问题,但如果强转成一个错误的类型,程序就会抛出一个异常。

    我们更希望能进行安全的强转,可以更优雅地处理强转出错的情况。

    这一点,Kotlin 在设计上自然也考虑到了,我们可以使用 as? 来解决:

    🏝️
    fun main() {
        var activity: Activity = NewActivity()
        // 👇'(activity as? NewActivity)' 之后是一个可空类型的对象,所以,需要使用 '?.' 来调用
        (activity as? NewActivity)?.action()
    }
    

    它的意思就是说如果强转成功就执行之后的调用,如果强转不成功就不执行。

    相关文章

      网友评论

          本文标题:Kotlin 的变量、函数和类型

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