【问题标题】:Interface's function clashes with Property's getterInterface 的函数与 Property 的 getter 冲突
【发布时间】:2016-07-15 11:34:25
【问题描述】:

接口的函数名故意与属性的getter名冲突,但由于意外覆盖问题被编译器禁止。是否可以指示编译器这是故意的?

interface A {
  fun getFoo()
}

class B: A {
  val foo
}

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    此功能似乎没有以任何方式实现。

    @AndreyBreslav 对similar question 的评论:

    目前您不能使用 Kotlin 属性覆盖 Java 方法。如果我们可以支持它会很好,但我们不知道如何为混合层次结构始终如一地做到这一点


    这并不能解决您的问题,但至少可以编译代码:您可以使用 @JvmName annotation 更改 getter 的 JVM 名称:

    interface A {
        fun getFoo(): SomeType
    }
    
    class B: A {
        override fun getFoo() = foo
    
        val foo: SomeType = someValue()
            @JvmName("getFoo_") get() = field
    }
    

    另外,考虑更改为更惯用的方法:在您的界面中定义 val-property,以便您可以在实现中覆盖它:

    interface A {
        val foo: SomeType
    }
    
    class B : A {
        override val foo: SomeType = someValue()
    }
    
    class C : A {
        override val foo: SomeType
            get() = someCustomGetter()
    } 
    

    【讨论】:

    • UPD:添加了更符合 Kotlin 习惯的方法。
    【解决方案2】:

    在我们坚持使用 Kotlin 之前,上述答案中的 Kotlin 惯用方法是可以的,但如果这些接口是用 Java 定义的,则它不适用。 KT-6653 中报告了很多提议,但目前都没有实施。我目前正在编写一些部分使用 Java 部分使用 Kotlin 的应用程序,这个问题完全扼杀了“Kotlin-Java 互操作性”的概念。

    我发现的唯一解决方法是:

    public interface A {
      String getFoo();
    }
    
    class B(private val _foo: String): A {
    
      override fun getFoo(): String = _foo
    
    }
    

    也可以用 setter 扩展这个类:

    class B(private var _foo: String): A {
    
      override fun getFoo(): String = _foo
    
      fun setFoo(foo: String) {
        _foo = foo
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-27
      • 2021-11-30
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2016-05-03
      相关资源
      最近更新 更多