隐式属性类型是否与显式属性类型相同?

时间:2017-07-19 00:39:17

标签: android oop kotlin design-principles

以下代码A来自Kotlin-for-Android-Developers。代码B由我编写。

这两个不同的代码块是否以相同的方式运行?

代码A

class DetailActivity : AppCompatActivity(), ToolbarManager {

    override val toolbar by lazy { find<Toolbar>(R.id.toolbar) }

    ...    
}

代码B

class DetailActivity : AppCompatActivity(), ToolbarManager {

    override val toolbar: Toolbar by lazy { find<Toolbar>(R.id.toolbar) }

    ...    
}

1 个答案:

答案 0 :(得分:3)

结构的角度来看,它们是相同的。 Kotlin编译器将发出源代码的相同java字节代码,如下所示:

private final Lazy<Toolbar> toolbarProvider = lazy(()-> find(R.id.toolbar));

public Toolbar getToolbar(){
       return toolbarProvider.getValue();
}

属性类型在上面的代码B 中是可选的,但是在通过接口编程而不是实现[1]时很有用,如果实现被更改,则唯一需要更改的是它被实例化,因为toolbar的使用根本无法访问其子类声明的功能。例如:

//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>()

编译器的角度来看,它们是不同的。由于编译器将在编译时推断代码A 中的实际属性类型,例如:

//                     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