protected 和 protected 的区别[this]

Difference between protected and protected[this]

我有以下代码:

class Base{
    protected val alpha ="Alpha";
    protected def sayHello = "Hello";
}
class Derived extends Base{
        val base = new Base;
        def hello = println(this.alpha +" "+this.sayHello) ;
       // def hello = println(base.alpha +" "+base.sayHello) ; // don't compile
    }

    object MyObj extends App{
            val x=new Derived;
            x.hello;
        }

在 class Base 中,如果我将 protected 标记为 this,代码将按预期工作;如果我不使用 this 标记它,一切也会按预期工作。

protectedprotected[this] 在 Scala 中等价吗?如果是,为什么 Scala 会提供两者?如果不是,它们有何不同?

不同的是,protected[this]子类实例只能访问它自己的字段(this.x),而protected子类可以访问所有实例中的字段(不是仅在 this):

class Base{
  protected val alpha ="Alpha";
  protected[this] def sayHello = "Hello";
}

class Derived extends Base{
  def hello = println(this.alpha +" "+this.sayHello) ;
  def hello2 = println(
   new Derived().alpha +" "
   +new Derived().sayHello) ; // error on "sayHello"
}

在此代码中,您可以访问 this.sayHello,但不能访问 other.sayHelloprotected alpha没有这个限制。

Scala protected 及其兄弟姐妹 protected[this]protected[pkg] 有点让人不知所措,但是我发现使用 Java[ 很容易记住解决方案=50=] protected 的哲学。 1st 如何在 Java

中看到受保护的成员
  1. 它们对subclass可见(subclass可能在同一个包或其他包中)
  2. 它们对与指定受保护成员 class 在同一包中的任何 class 可见。

显然它们对 class 本身是可见的。

但 Scala 对 subclass.By 默认情况下它们的可见性有一些限制,它们仅对 subclass 可见。它们对声明 class 的包不可见。但是存在两种情况,它们在 subclass 中的可见性。

如果受保护的成员不合格(普通受保护),则可以通过 另一个声明实例可见 class 声明 class 以及 this 到 class 和 subclass 例如

class Base{
    protected val alpha ="Alpha";
    protected def sayHello = "Hello";
}
class Derived extends Base{
        def hello = println((new Derived()).sayHello) ;
        def hello2 = println(this.sayHello);

}

如果受保护的成员用this限定。它只能用class和子class中的this访问,它不能被声明 class 或 subclass 的其他实例访问,例如

class Base{
    protected val alpha ="Alpha";
    protected[this] def sayHello = "Hello";
    def foo = Console println(new Base().sayHello) // won't compile
    def bar = Console println(this.sayHello)
}
class Derived extends Base{
        def hello = println(this.sayHello) ;
        //def hello2 = println((new Derived() .sayHello) // won't compile
}

因为 Scala 默认不支持受保护成员的包级别访问。但是如果你想让它在包级别可用,那么你需要明确指定包,例如protected[pkg]。现在,如果在 pkg 或以下声明的 classes 中访问此受保护成员,则声明 class/Subclass 实例时可见。

例如

package com.test.alpha{
class Base{
    protected val alpha ="Alpha";
    protected[test] def sayHello = "Hello"; // if you remove [test] it won't compile
}

class Derived extends Base{
    val base = new Base
        def hello = println(base.sayHello) ;
}}

这就是人们如何记住 Scala protected