隐式属性类型是否与显式属性类型相同?
以下代码A来自Kotlin for Android开发人员。 代码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) } ... }
从结构上看,它们是一样的。 Kotlin编译器将会发出与源代码相同的Java字节代码,如下所示:
private final Lazy<Toolbar> toolbarProvider = lazy(()-> find(R.id.toolbar)); public Toolbar getToolbar(){ return toolbarProvider.getValue(); }
在上面的代码B中属性类型是可选的,但是当通过接口而不是实现编程时,它是有用的,如果实现被改变了,唯一需要改变的是实例化的地方,因为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. //eg: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