我有以下类结构:
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来说是合法的。
- protected - 仅在此类中可见+在子类中可见;
是错误还是预期的行为?
答案 0 :(得分:5)
这是设计行为
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
答案 1 :(得分:3)
目前的行为是设计上的。
通过调用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
}
}
protected
ParentCl
的乐趣。它会正常工作。protected
变量。它会正常工作。protected
有趣 。这不起作用。 protected
更改为internal
或public
。private val subChild = Child()
。 注意:如果您使用来自ParentCl的其他子的m(),您需要扩大子类内的可见范围:public override fun m() {...}
答案 2 :(得分:0)
这可能是一个错误。
当我添加{}时,一切都变好了。
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/
答案 3 :(得分:0)
受保护的-与私有+相同,也可以在子类中看到;
elif isinstance(u.port, type(None)):
print(' None')
在您的子类中
abstract class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutResId())
}
protected open fun getPageTitle() = SpannableString(getString(R.string.app_name))
}
有关详细信息,请参阅文档