Java私有静态最终字段和匿名内部类与Kotlin常量和对象表达式/声明

时间:2019-03-03 01:43:38

标签: java class oop object kotlin

假设我有一个Kotlin界面:

interface Dog {
    fun walk()
}

我想创建一个Kotlin object of this class with slight modifications,就像这样:

val poodle : Dog = object : Dog {

    override fun walk() {
        ...
    }
}

但是,我还想向此对象添加一个等效于Java中的私有static final字段的东西,就像这样(这是Java中的一个有效示例):

Dog poodle = new Dog() {

    private static final String POODLE_FASHION = ...

    @Override
    public walk() {
        ...
    }
}

我读到私有常量在Kotlin中与此等效。我尝试执行以下(这是Kotlin中无法正常工作的示例)

val poodle : Dog = object : Dog {

    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

这样做时,我在Android Studio中遇到以下错误:仅在顶层或对象中允许使用常量“ val”

有人可以解释为什么Java版本有效,但Kotlin版本无效吗?如何为Kotlin做到这一点(我已经尝试了伴侣对象,但收到错误修饰符“ companion”不适用于“本地类” )?请注意,我不想执行以下操作,因为我希望POODLE_FASHION位于val poodle内部,因为我还要创建其他经过稍微修改的Dog对象(val pug,{{1 }}等)

val chihuahua

谢谢!

2 个答案:

答案 0 :(得分:1)

val poodle : Dog = object : Dog {

    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

在此示例中,根本没有任何理由POODLE_FASHION必须是静态或常量。它可以只是普通的val,而且不会花任何额外费用。

也就是说,听起来您应该拥有Poodle类,而不是对象。

答案 1 :(得分:0)

请注意对象表达式和对象声明之间的区别。

  • val poodle = object: Dog { ... }object expression。它创建一个匿名对象。相当于用Java编写Dog poodle = new Dog() { ... }
  • object Poodle: Dog { ... }object declaration。它创建一个单例对象,大致等效于创建一个Java类,该类仅限于只有一个实例。

Kotlin文档指出const val属性必须是“顶层的,或者是对象声明或伴随对象的成员”。 (https://kotlinlang.org/docs/reference/properties.html#compile-time-constants)。它们在对象表达式中无效。

以下对象声明应该可以正常工作:

object Poodle : Dog {
    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

区别的一个重要原因是对象表达式未声明新类型(尽管用Java来讲,它确实会导致一个匿名类)。

  • val poodle = object: Dog { ... }创建类型为Dog的变量。没有Poodle这样的类型。
  • object: Poodle: Dog { ... }创建一个Poodle类型的对象。这是一种新类型,它是Dog的子类型。

这一区别很重要,因为在Kotlin中,const val属性始终属于一种类型。 MyClass.MY_CONST_VAL是有效的,但是以MyClass().MY_CONST_VAL的身份访问它是错误的,将不起作用。结果,匿名对象上的const val属性将始终是该对象的有效私有对象。

我看不到技术上的原因,为什么不可能在匿名对象上允许const val属性(Java内部类中允许使用static final编译时常量字段),但是它们的实用性将受到严格限制,而这并不是Kotlin语言规范的一部分。

相关问题