访问基类的受保护成员

时间:2016-06-02 01:48:06

标签: scala inheritance protected companion-object

我不经常使用继承,所以我不确定为什么它不起作用。在我的项目中,我有以下内容:

基础密封类,受保护成员:

sealed class TheRoot {
  protected def some: String = "TheRoot"
}

它的后代有一些逻辑:

final case class Descendant() extends TheRoot {
  def call: Unit = { 
    val self: TheRoot = this
    self.some // <<- throw compilation error
  }
}

编译上面给出了以下错误:

error: method some in class TheRoot cannot be accessed in TheRoot
 Access to protected method some not permitted because
 prefix type TheRoot does not conform to
 class Descendant where the access take place
           self.some

我不确定从超类中调用受保护成员的问题是什么......但是如果我们将它包装到伴随对象中它会变得更有趣,它会神奇地修复它问题:

sealed class TheRoot {
  protected def some: String = "TheRoot"
}

object TheRoot {
  final case class Descendant() extends TheRoot {
    def call: Unit = {
      val self: TheRoot = this
      self.some // <<- NO ERROR!
    }
  }
}


// Exiting paste mode, now interpreting.

defined class TheRoot
defined object TheRoot

1 个答案:

答案 0 :(得分:1)

document

中所述
  

对受保护成员的访问也比Java更具限制性。在Scala中,受保护的成员只能从定义成员的类的子类访问。在Java中,也可以从同一包中的其他类进行访问。在Scala中,还有另一种方法可以实现这种效果,如下所述,因此受保护可以自由保留原样。显示的示例说明了受保护的访问:

 package p {
  class Super {
    protected def f() { println("f") }
  }
  class Sub extends Super {
    f()
  }
  class Other {
    (new Super).f()  // error: f is not accessible
  }
}

在您的代码中,如果您将self.some更改为some,那就没问题了。

虽然伴随对象可以访问其伴随类的任何成员,因此对象Descendant的{​​{1}}可以访问TheRoot

的受保护方法