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

Kotlin无法访问受保护的抽象方法,kotlin,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' } 我遇到一个异常K

我的课程结构如下:

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:无法访问'm':它在'Abstr'中受保护。

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

  • 受保护-仅在该类中可见+在子类中也可见
是bug还是预期行为?

可能是bug

当我添加{}时,一切都正常了

abstract class Abstr{
    protected abstract fun m()
}

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

    override fun m() {
        subChild.m() // Compiles fine
    }
}
在上创建问题

或是写得松懈

当前行为是设计的

通过调用
subChild.m()
您试图从对象外部访问
absr
的实例,因此
protected
access阻止您这样做

让我给你举个简单的例子来澄清这个问题
  • 您正在从child类调用
    protected
    ParentCl
    的乐趣。它会很好用的
  • 您正在修改子类中受保护的
    变量。它会很好用的
  • 您正在调用子类上下文之外的
    受保护的
    乐趣。这是行不通的
  • 根据您的目标,有两种解决方案:
  • 如果要从ParentCl调用m(),则需要将可见性从
    受保护的
    更改为
    内部的
    公共的
  • 如果要从子类调用m(),则需要声明不带其父类显式类型的变量:
    private val subChild=child()

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

    这是设计行为

    Kotlin中的受保护修饰符类似于Java,但有额外的限制

    受Java保护

    • 对继承可见
    • 在包中可见
    受科特林保护

    • 对继承可见
    因此,根据相关代码,我们无法访问受保护的方法

    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团队的问题追踪器中有答案:
    受保护-与private+相同,在子类中也可见

    abstract class BaseActivity : AppCompatActivity() {
       override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutResId())
    
    } 
    
       protected open fun getPageTitle() = SpannableString(getString(R.string.app_name))
    }
    
    在你们班

    class EditProfileActivity : BaseActivity() {
        override fun getPageTitle(): SpannableString = SpannableString(getString(R.string.edit_profile))
    }
    
    有关更多详细信息,请参阅文档


    您使用了
    subChild:Child=Child()
    ,这就是为什么“一切正常”不是因为Kotlin的bug。原始代码明确定义了类型:
    subChild:absr=Child()
    @Val噢,忘了往回改,反正代码编译得很好。谢谢您的编辑。@icarumbas您的代码无法编译。和我一样的错误
    class EditProfileActivity : BaseActivity() {
        override fun getPageTitle(): SpannableString = SpannableString(getString(R.string.edit_profile))
    }