【问题标题】:Protected Members of Other Instances in ScalaScala 中其他实例的受保护成员
【发布时间】:2011-06-05 01:04:18
【问题描述】:

我在学习 Scala 时遇到了困难。我有一个基本上等同于这个的继承层次结构:

class A {
    protected def myMethod() = println("myMethod() from A")
}

class B extends A {
    def invokeMyMethod(a: A) = a.myMethod()
}

但尝试编译此示例时,我收到错误“test.scala:7: error: method myMethod cannot be access in A”。

来自 Java,我的理解是受保护的成员应该可以在任何时候从派生类访问,而且我在任何地方都没有看到任何东西告诉我 Scala 中的受保护成员受实例限制。有人对此有解释吗?

【问题讨论】:

    标签: scala protected


    【解决方案1】:

    引用Scala Language Specification

    受保护的标识符 x 可以用作选择 r .x 中的成员名称 仅当满足以下条件之一时:

    – 访问在定义成员的模板内,或者,如果给定了限定条件 C,则在包 C、类 C 或其伴随模块内,或者

    --r是this和super的保留字之一,或者

    – r 的类型符合包含访问权限的类的类型实例。

    这三个规则定义了一个实例何时可以访问另一个实例的受保护成员。值得注意的一点是,根据最后一条规则,当B 扩展A 时,A 的实例可以访问B 的不同实例的受保护成员...但@987654326 的实例@ 不能访问另一个 A 的受保护成员!换句话说:

    class A {
        protected val aMember = "a"
        def accessBMember(b: B) = b.bMember // legal!
    }
    
    class B extends A {
        protected val bMember = "b"
        def accessAMember(a: A) = a.aMember // illegal!
    }
    

    【讨论】:

    • 这个解释实际上并没有说明为什么 OP 的代码不起作用。 B A 的派生类型,就像它应该的那样。
    • B 派生自A,但它试图访问的不是它自己的受保护成员myMethod,而是另一个实例的参数a: A。受保护的成员仅对包含它的实例可见(默认情况下,尽管可以使用我提到的范围注释进行修改)。
    • 这与您引用的段落相矛盾:“包括相同类型的其他实例和任何派生类型。”
    • @Submonoid - 你是完全正确的,报价并不真正适用。请查看我对回复的修改。
    • -1 这个答案应该是 3-5 句长。编辑之前的一切都是浪费时间。
    猜你喜欢
    • 2012-11-27
    • 2016-08-21
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 2013-09-17
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多