Kotlin无法访问受保护的抽象方法

我有以下的类结构:

abstract class Abstr{ protected abstract fun m() } class Child : Abstr(){ private val subChild: Abstr = Child() override fun m() = subChild.m()// Error:(12, 18) Kotlin: Cannot access 'm': it is protected in 'Abstr' } 

我遇到了一个异常Kotlin: Cannot access 'm': it is protected in 'Abstr'

这有点混乱,因为相同的结构是合法的Java。

根据kotlin文档

  • protected – 仅在此类中可见+在子类中也可见;

它是错误还是预期的行为?

目前的行为是由设计。

通过调用subChild.m()你试图从对象之外访问一个subChild.m()的实例,所以protected访问阻止你这样做。

让我来举个简单的例子来澄清一下这个案子

  abstract class ParentCl { protected var num = 1 protected open fun m(){ } } class ChildCl : ParentCl() { private val a0 : ParentCl = ChildCl() override fun m() { super.m() // 1-st case num = 2 // 2-nd case a0.m() // 3-rd case } } 
  1. 你正在调用protected ParentCl从子类中获得乐趣。 它会正常工作。
  2. 您正在修改子类的protected变量。 它会正常工作。
  3. 你在孩子班级的环境之外调用protected乐趣。 这是行不通的。

取决于你的目标是什么,有两个解决方案:

  1. 如果您想从ParentCl中调用m(),则需要将protected的可见性更改为internalpublic
  2. 如果你想从子类中调用m(),你需要声明变量而不需要父类的显式类型: private val subChild = Child()

注意:如果您将使用 ParentCl的其他子项中m(),则需要放大子类中的可见性范围: public override fun m() {...}

这可能是一个错误。

当我加入{}时,一切都变好了。

 abstract class Abstr{ protected abstract fun m() } class Child : Abstr(){ private val subChild: Abstr = Child() override fun m() { subChild.m() // Compiles fine } } 

https://discuss.kotlinlang.org/上创建问题

或在Slack http://slack.kotlinlang.org/上写