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 } }
- 你正在调用
protected
ParentCl
从子类中获得乐趣。 它会正常工作。 - 您正在修改子类的
protected
变量。 它会正常工作。 - 你在孩子班级的环境之外调用
protected
乐趣。 这是行不通的。
取决于你的目标是什么,有两个解决方案:
- 如果您想从ParentCl中调用m(),则需要将
protected
的可见性更改为internal
或public
。 - 如果你想从子类中调用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/上写