我设计了一个相当简单的例子来说明我的观点如下:
abstract class AbstractSuperClass {
protected def someFunction(num: Int): Int
def addition(another: AbstractSuperClass, num: Int): Int
}
class SubclassSquare extends AbstractSuperClass {
override protected def someFunction(num: Int): Int = num * num
override def addition(another: AbstractSuperClass, num: Int): Int =
someFunction(num) + another.someFunction(num)
}
Run Code Online (Sandbox Code Playgroud)
我在执行代码时收到以下错误消息。(当然,main函数是正确定义的。)
错误:(12, 33) 类 AbstractSuperClass 中的方法 someFunction 无法在 AbstractSuperClass 中访问 访问受保护的方法 someFunction 不允许,因为前缀类型 AbstractSuperClass 不符合发生访问的类子类 someFunction(num) + another.someFunction(num)
该方法addition导致了问题。该代码尝试访问AbstractSuperClass实例的受保护字段,但从我的角度来看,这里应该不会引起任何问题,因为SubclassSquare是AbstractSuperClass.
但是,我知道这里一定有我不明白的地方。我想知道如何更改我的代码以使其编译。好评。
小智 5
在 scala 中,protected 比 java 中的限制更多。
我发现这个答案在理解 scala 的受保护修饰符时非常有帮助。
如果受保护的成员没有限定(即它只是普通受保护的),那么它对于另一个声明类到声明类的实例以及
this到类和子类中都是可见的。
因此,您可以SubclassSquare按如下方式修改加法函数:
override def addition(another: AbstractSuperClass, num: Int): Int =
someFunction(num) + another.asInstanceOf[SubclassSquare].someFunction(num)
Run Code Online (Sandbox Code Playgroud)
这段代码可以编译,但如果参数不是 的实例,它会崩溃SubclassSquare,所以这不是一个好的解决方案。
更好的方法是使用访问限定符。所以你只需要用 protected 修饰符指定你的包名,例如protected[yourPackageName]. 这样做将使您的受保护成员可以在声明的包或以下包中的类中访问。所以你的代码看起来像:
abstract class AbstractSuperClass {
protected[yourPackageName] def someFunction(num: Int): Int
def addition(another: AbstractSuperClass, num: Int): Int
}
class SubclassSquare extends AbstractSuperClass {
override protected[yourPackageName] def someFunction(num: Int): Int = num * num
override def addition(another: AbstractSuperClass, num: Int): Int =
someFunction(num) + another.someFunction(num)
}
Run Code Online (Sandbox Code Playgroud)
您可以扩大访问范围:
package prot
abstract class AbstractSuperClass {
protected[prot] def someFunction(num: Int): Int
def addition(another: AbstractSuperClass, num: Int): Int
}
class SubclassSquare extends AbstractSuperClass {
override protected[prot] def someFunction(num: Int): Int = num * num
override def addition(another: AbstractSuperClass, num: Int): Int = someFunction(num) + another.someFunction(num)
}
Run Code Online (Sandbox Code Playgroud)
规格词:
受保护的标识符 x 可以用作选择 rx 中的成员名称
仅当以下情况之一适用时:
访问位于定义成员的模板内,或者,如果给出了资格 C,则位于包 C、类 C 或其伴随模块内,或者
r 是 this 和 super 的保留字之一,
或 r 的类型符合包含访问权限的类的类型实例。
因此,访问权限取决于您的选择。
你遇到了第三个条件,第一个条件就是补救措施。