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

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

    ...    
}

最佳答案

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

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

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

属性类型在上面的代码B 中是可选的,但在通过接口(interface)而非实现进行编程时很有用[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

关于android - 隐式属性类型是否与显式属性类型相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45179193/

相关文章:

android - 单例被摧毁

android - 在android中通过选项卡传递数据

JavaScript 对象 : How do Regular Expression objects get passed?

spring - 如何将 kotlin 协程与响应式 Spring 数据一起使用

kotlin - Kotlin:出现 ')'错误,代码未运行

android - Cover Flow 功能使用 view pager android

android - Spring 和 Jackson Mapper 无法从 START_OBJECT 中反序列化 CUSTOM_CLASS 的实例

java - 如何根据子类类型调用java方法?

java - 为子类设置父类(super class)属性

android - KOTLIN:基本异步/协程