Kotlin 的变量、函数和类型

2019-12-16  本文已影响0人  吐必南波丸

变量

变量声明:var 、val 、lateinit

var name: String? =null
这种类型之后加 ? 的写法,在 Kotlin 里叫可空类型
    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 {
    ...
}

基本类型

🏝️
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"

类和对象

🏝️
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() {
                        👆
}
🏝️
// 👇写法会报错,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() {}

类型的判断和强转

🏝️
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()
}

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

上一篇下一篇

猜你喜欢

热点阅读