我想在特定的上下文中使用Kotlin 委托。
printMessage(),我仍然需要以与多态继承中调用的方式相同的方式调用委托super.printMessage()。我可以通过简单地在子句中实例化匿名委托来完成第一个任务by(class Derived() : Base by BaseImpl(42)使用Kotlin 的文档示例)。但是,这阻止了我访问匿名委托,因为我不知道如何引用它。
我想做类似以下的事情。然而,以下内容编译时不会出现错误'this' is not defined in this context。
class Derived() : Base by this.b {
val b: Base = BaseImpl(42)
override fun printMessage() {
b.printMessage()
print("abc")
}
}
Run Code Online (Sandbox Code Playgroud)
我确实需要为班级的每个实例分配一个单独的委托Derived。因此,作为全局变量移动b对我来说不是一个选择。
我最接近我需要的是构造函数的可选参数。这也不是一个好的选择,因为我不想允许Derived用任意的代表构建我的类。
我正在尝试将delegates/observable与vetoable结合起来(在查看源 kotlin.properties.Delegates.kt 后这不是问题),但是在尝试将属性存储在 map 中时事情变得棘手。
或者换句话说,如何将这三者结合起来:
var k1: Int by Delegates.observable(0) { property, oldValue, newValue ->
println("Hi from k1 observer")
}
var k2:Int by Delegates.vetoable(0) {property, oldValue, newValue ->
println("Hi from k2 more-than check")
oldValue > newValue
}
val myMap = mutableMapOf<String, Int>()
var k3 by myMap
Run Code Online (Sandbox Code Playgroud) 我创建了一个自定义属性,专门用于保存需要为我的一个项目调用 invalidate() 的视图属性:
class InvalidatingProperty<T>(private var _value: T) {
operator fun getValue(thisRef: View, property: KProperty<*>): T {
return _value
}
operator fun setValue(thisRef: View, property: KProperty<*>, value: T) {
_value = value
thisRef.invalidate()
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个项目中,我想重用我以前的一些工作,所以我将视图及其依赖项(包括 InvalidatingProperty)复制到一个新项目中。但在新项目中,使用 InvalidatingProperty 会导致预览渲染失败,并出现以下异常:
java.lang.NoSuchMethodError: kotlin.jvm.internal.MutablePropertyReference1Impl.<init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
at com.gradesimulator.views.SummaryView.<clinit>(SummaryView.kt)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:403)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:186)
at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:144)
at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:309)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:416)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:427)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:331)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:1123)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1097)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:501) …Run Code Online (Sandbox Code Playgroud) 我如何使用 jackson(反)序列化 kotlin 委托属性。我有一堂这样的课
class MyClass {
var a: Int = 42
set(value) {
val changed = field != value
field = value
if (changed) notifyListeners()
}
... and a dozen other properties that all follow this pattern ...
}
Run Code Online (Sandbox Code Playgroud)
我想通过使用来简化它
class MyClass {
var a: Int by NotifyUiOnChange(42)
...
private inner class NotifyUiOnChange<T>(initialValue: T) : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) {
notifyUiListeners()
}
}
}
Run Code Online (Sandbox Code Playgroud)
但随后杰克逊将忽略该属性。
无论如何,我如何告诉杰克逊序列化和反序列化该属性?然后我如何应用 @JsonIgnore 注释(或类似的东西)?
当覆盖由类委托实现的接口方法时,是否可以从覆盖函数中调用通常委托给该类的类?类似于super使用继承时的调用方式。
从文档中:
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // prints 10
}
Run Code Online (Sandbox Code Playgroud)
请注意,重写将按您期望的那样工作:编译器将使用重写实现,而不是委托对象中的实现。
override fun print() { ... }
Run Code Online (Sandbox Code Playgroud)
如何BaseImpl print()从此重写函数中调用该函数?
用例是我想在重用现有实现的同时向此功能添加其他逻辑。