3

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

具有受保护成员的基本密封类:

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
4

1 回答 1

1

文档中所述

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

 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.somesome,就可以了。

而伴生对象可以访问其伴生类的任何成员,因此Descendantof 对象TheRoot可以访问受保护的方法some

于 2016-06-02T02:18:01.320 回答