Search code examples
androidoopkotlindesign-principles

Is an implicit property type same with an explicit property type?


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) }

    ...    
}

Solution

  • 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