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' } 

我遇到了一个exceptionKotlin: 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. 您正在修改子类的protectedvariables。 它会正常工作。
  3. 你在孩子class级的环境之外调用protected乐趣。 这是行不通的。

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

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

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

这是设计的行为

Kotlin中受保护的修饰符类似于Java,但有其他限制。

在Java中保护

  • 可见的吸入性
  • 在包中可见

保护在Kotlin

  • 可见的吸入性

所以,根据有关的代码,我们无法访问受保护的方法

 class Child : Abstr(){ private val subChild: Abstr = Child() override fun m() = subChild.m() //Trying to access not inherited method } 

Java中有类似的限制,当我们试图从另一个包中访问受保护的成员时:

 // FILE: a/SuperClass.java package a; public class SuperClass { protected void superFunction() {} } // FILE: b/ChildClass.java package b; public class ChildClass extends SuperClass { void testFunction() { ((SuperClass) new ChildClass()).superFunction(); // ERROR: superFunction() has protected access in a.SuperClass } } 

Kotlin团队的问题跟踪器中有答案: https : //youtrack.jetbrains.com/issue/KT-21048

这可能是一个错误。

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

 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/上写