【问题标题】: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

【问题讨论】:

    标签: scala inheritance protected companion-object


    【解决方案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 无效
    猜你喜欢
    • 2019-12-05
    • 2016-07-15
    • 2019-01-20
    • 2014-08-27
    • 2017-08-01
    • 2014-01-26
    • 2014-02-22
    • 2022-01-06
    相关资源
    最近更新 更多