Smart casts

If you are wondering how, in the previous section, we called functions that belong to supertypes from the base SuperHero type, and the compiler did not complain, the answer is the smart casting feature of the Kotlin compiler. Whenever you check in an if or a when statement that a type can be cast to another type, the compiler then allows you to access all members from the target type, that is, the compiler does the cast for you. Let's say we have a class hierarchy like the following one:

open class BaseUser(val name: String)

open class User(name: String,
val birthYear: Int) : BaseUser(name) {
fun login() {
}
}
open class AdminUser(name: String,
birthYear: Int) : User(name, birthYear) {
fun accessLogs() {
}
}

We have a function that accepts the base type; we can check with the is keyword whether a type is an instance of another type. When the compiler knows that a type is actually an instance of a different type, you can immediately access all the members without casting:

fun smartCasting(baseUser: BaseUser) {
if (baseUser is User) {
baseUser.login()
} else if (baseUser is AdminUser) {
baseUser.accessLogs()
}
}

Smart casting has some rules that need to be satisfied. The compiler has to be sure that a variable will not change after the instance of check. This rules out mutable fields and properties (var properties). The compiler cannot ensure that after a successful instance check, some other thread didn't modify it. This leaves smart casting usable by immutable properties (val properties) and local variables that are not accessed inside a closure (modified by a lambda function or an anonymous object).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.136.168