Scala protected 和它的兄弟protected[this] ,protected[pkg] 有点压倒性,但是我发现使用protected 的Java 哲学很容易记住解决方案。
1st 如何在 Java 中看到受保护的成员
- 它们对子类可见(子类可能在同一个包或其他包中)
- 它们对于与指定受保护成员的类在同一包中的任何类都是可见的。
显然它们对类本身是可见的。
但是 Scala 对它们如何对子类可见有一些限制。默认情况下,它们只对子类可见。它们对于声明哪个类的包是不可见的。但是存在两种情况,它们在子类中是如何可见的。
如果受保护的成员不合格(纯受保护),那么它在 另一个声明类的实例 到声明类以及 this 到类和子类中可见,例如强>
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限定。它只能在类和子类中用this访问,它不能被声明类或子类的其他实例访问,例如
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 或以下声明的类中访问该受保护成员,则通过声明类/子类实例可以看到它们。
例如
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