可以在 kotlin 的对象表达式中扩展抽象 class 吗?

Can an abstract class be expanded within an object expression in kotlin?

所以我正在编写一段代码,将暂停和恢复功能添加到抽象 class CountDownTimer (Android.os.CountDownTimer) 中。我仅在这个 activity 中使用该功能,因此我只是使用一个对象表达式来创建一个名为 sequencetimer 的匿名 class。代码看起来像这样:

public var sequencetimer = object : CountDownTimer(30000, 1000) {
    public var timeremaining : Long = 0

    override fun onTick(millisUntilFinished: Long) {
        findViewById<TextView>(R.id.textView8).apply {
            text = ("seconds remaining: " + millisUntilFinished / 1000)
        }
    }

    override fun onFinish() {
        findViewById<TextView>(R.id.textView8).apply {
            text = "done"
        }
    }

    public fun pauseTimer() {
        timeremaining = findViewById<TextView>(R.id.textView8).text as Long
        cancel()
    }

    public fun resumeTimer() {
        onTick(timeremaining)
        start()
    }
}

现在我想调用我在 activity 暂停或恢复时添加的 pauseTimer 和 resumeTimer 函数,如下所示:

override fun onPause() {
    super.onPause()
    sequencetimer.pauseTimer()
}

override fun onResume() {
    super.onResume()
    sequencetimer.resumeTimer()
}

然而,代码不断向我抛出函数 pauseTimer() 和 resumeTimer() 的未解决引用错误,即使在 activity class 中声明了 sequencetimer 对象,我可以执行所有其他功能,例如 sequencetimer.onTick() 和 sequencetimer.start() (但是我也无法访问 public var timeremaining)。有谁知道这里的问题是什么?还是在匿名对象表达式中 expand/extend 抽象 class 根本不可能(我本以为 android studio 会抛出某种类型的错误)?

您的代码存在一些问题。

我看到的第一个问题是public var sequencetimer。使用 kotlin 关键字 public, protected, internal,您可以向编译器声明 sequencetimer 可以在您的 android activity class 范围之外访问。但是 object 在您的 activity class 中创建为匿名 class。 Kotlin 编译器决定唯一的解决方案是将 sequencetimer 标记为 CountDownTimer.

// byte code
public final getSequencetimer()Landroid/os/CountDownTimer;
  @Lorg/jetbrains/annotations/NotNull;() 

其次,resumeTimer() 将调用 onTick(12345L) 一次并从 millisInFuture 30_000L.

重新启动计时器

最好为剩余时间创建一个新的倒数计时器。 请减少倒计时间隔,否则您会看到秒数不一致 30, 28, 27, 26, 26, 24, ...

希望对您有帮助。

正如您自己所说:您创建了 anonymous class。这意味着从开发人员的角度来看 class 不存在并且 sequencetimer 的类型只是 CountDownTimer 而没有 pauseTimer()resumeTimer()职能。您需要创建一个正则,命名为class,以便在代码中引用它。

或者,您可以将 sequencetimer 设为 private var。在这种情况下,Kotlin 假定这是内部的东西并提供了某种捷径。它有条件地允许这种操作,即使通常它不应该是可能的。文档中描述了此行为:https://kotlinlang.org/docs/object-declarations.html#using-anonymous-objects-as-return-and-value-types