The following Code A is from Kotlin-for-Android-Developers. The Code B is written by me.
Do these two different blocks of code function the same way?
Code A
class DetailActivity : AppCompatActivity(), ToolbarManager {
override val toolbar by lazy { find<Toolbar>(R.id.toolbar) }
...
}
Code B
class DetailActivity : AppCompatActivity(), ToolbarManager {
override val toolbar: Toolbar by lazy { find<Toolbar>(R.id.toolbar) }
...
}
From the structure point of view, they are the same. the Kotlin compiler will emits the same java byte code of the source code both likes as below:
private final Lazy<Toolbar> toolbarProvider = lazy(()-> find(R.id.toolbar));
public Toolbar getToolbar(){
return toolbarProvider.getValue();
}
the property type is optional in code B above, but it is useful when programming by interface rather than implementation [1], if the implementation was changed the only one need to change is where it is instantiated, since the usage of the toolbar
can't access the features declared by its sub-classes at all. for example:
//declare as abstract supertype ---v
override val toolbar: AbstractToolbar by lazy { find<Toolbar>(R.id.toolbar) }
// ^
//when implementation was changed only need to change here.
//e.g:change the `Toolbar` to other subtype of AbstractToolbar: find<MiniToolbar>()
From the compiler point of view, they are different. Since the compiler will infer the actual property type in the code A at compile-time, for example:
// v--- the property type `Toolbar` is inferred at compile-time
override val toolbar/*:Toolbar*/ by lazy { find<Toolbar>(R.id.toolbar) }
[1]: https://en.wikipedia.org/wiki/Liskov_substitution_principle