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

Ser*_*iuk 8 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'
}
Run Code Online (Sandbox Code Playgroud)

我有一个例外 Kotlin: Cannot access 'm': it is protected in 'Abstr'

这有点令人困惑,因为相同的结构对于java来说是合法的.

根据kotlin docs

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

是bug还是预期的行为?

Val*_*Val 5

当前行为是设计使然。

通过调用,subChild.m()您试图Abstr从对象外部访问 的实例,因此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
        }
    }
Run Code Online (Sandbox Code Playgroud)
  1. 您正在protected ParentCl从子类中调用's fun。它会正常工作。
  2. 您正在修改protected子类中的变量。它会正常工作。
  3. 你在子类的上下文之外调用protected乐趣。这是行不通的。

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

  1. 如果您想从 ParentCl 调用 m(),您需要将可见性从 更改protectedinternalpublic
  2. 如果你想从子类中调用M()需要声明的变量没有明确的类型其父:private val subChild = Child()

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


Ser*_*iuk 5

这是设计的行为

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

受Java保护:

  • 可见继承
  • 在包装中可见

受保护在Kotlin:

  • 可见继承

因此,根据有问题的代码,我们无法访问受保护的方法

class Child : Abstr(){
    private val subChild: Abstr = Child()

    override fun m() = subChild.m() //Trying to access not inherited method 
}
Run Code Online (Sandbox Code Playgroud)

当我们尝试从另一个包访问受保护的成员时,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
    }
}
Run Code Online (Sandbox Code Playgroud)

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