访问基类的受保护成员

Posted

技术标签:

【中文标题】访问基类的受保护成员【英文标题】:Accessing a protected member of a base class 【发布时间】:2016-10-01 13:45:27 【问题描述】:

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

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

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】:

如document中所述

对受保护成员的访问也比在 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.some 更改为some,就可以了。

而伴生对象可以访问其伴生类的任何成员,所以对象TheRootDescendant可以访问some的受保护方法

【讨论】:

我需要向上转换当前对象的类型,我的例子是简化的。在您的报价中,您还有a protected member is only accessible from subclasses of the class,这就是我要问的原因,对我来说DescendantTheRoot 的子类。我知道伴随对象的机制,但我不清楚为什么在这种情况下它允许受保护的访问 为什么需要将this 向上转换为超类型?您可以在接受子类型的任何地方使用子类型(当然,逆变参数除外)...无论如何,将受保护成员的范围限定为封闭包(protected[p] def some: String = ...)也应该像您的示例一样使用封闭Descendant对象。 @4lex1v 对不起,我之前误解了你的问题。我发现了另一个奇怪的事情。 this.some 有效,但 self.some 无效

以上是关于访问基类的受保护成员的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 访问基类的受保护/私有成员

如何防止基类的受保护成员仍然在子类的第二级被访问?

C++ 派生模板类:访问实例的受保护成员

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

protectedpublicprivate

protected 成员与派生类