采用抽象超类实例和“不允许访问受保护方法”错误的受保护方法
Posted
技术标签:
【中文标题】采用抽象超类实例和“不允许访问受保护方法”错误的受保护方法【英文标题】:protected method that takes an abstract super class instance and the "access to protected method not permitted" error 【发布时间】:2020-04-23 01:39:36 【问题描述】:我设计了一个相当简单的例子来说明我的观点,如下所示:
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)
我在执行代码时收到以下错误消息。 (当然,main
函数是正确定义的。)
Error:(12, 33) 类 AbstractSuperClass 中的方法 someFunction 无法在 AbstractSuperClass 中访问 不允许访问受保护的方法 someFunction,因为 前缀类型 AbstractSuperClass 不符合 class 访问发生的子类 someFunction(num) + another.someFunction(num)
addition
方法导致了问题。该代码尝试访问 AbstractSuperClass
实例的受保护字段,但从我的角度来看,它在这里应该没有问题,因为 SubclassSquare
是 AbstractSuperClass
的子类。
但是,我知道这里肯定有一些我不明白的地方。我想知道如何更改我的代码以使其编译。好评。
【问题讨论】:
您似乎无法访问另一个实例上的protected
字段。但是,这对我来说似乎是一个错误。
是的,通常你可以访问另一个对象的受保护字段,只要它们都是同一个类的实例。从技术上讲,参数another
和this
都是AbstractSuperClass 的实例,所以人们会认为它有效,但显然不是。
开场截击加一个,或者如果你愿意,莎莉。我希望他们为错误跟踪器添加一个模板,开头是:“我设计了一个相当简单的例子来说明我的观点,如下所示。”
【参考方案1】:
您可以扩大访问范围:
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)
规范词:
受保护的标识符 x 可以用作选择中的成员名称 r.x
仅在以下情况之一适用时:
访问权限在定义成员的模板内,或者,如果资格 C 在包 C 或类 C 或其伴侣中给出 模块,或
r 是 this 和 super 的保留字之一,
或 r 的类型符合包含访问权限的类的类型实例。
所以访问权限取决于您选择的内容。
你违反了第三个条件,第一个是补救措施。
【讨论】:
【参考方案2】:在 scala 中,protected 比在 java 中更严格。
我发现 this answer 在理解 scala 的受保护修饰符时非常有帮助。
如果受保护的成员不合格(即它只是普通受保护的) 然后它与另一个声明类的实例可见 将类以及
this
声明到类和子类中。
所以你可以修改SubclassSquare
中的加法函数如下:
override def addition(another: AbstractSuperClass, num: Int): Int =
someFunction(num) + another.asInstanceOf[SubclassSquare].someFunction(num)
这段代码可以编译,但如果参数不是SubclassSquare
的实例,它会崩溃,所以这不是一个好的解决方案。
更好的方法是使用访问限定符。因此,您只需要使用受保护的修饰符指定您的包名称,例如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)
【讨论】:
以上是关于采用抽象超类实例和“不允许访问受保护方法”错误的受保护方法的主要内容,如果未能解决你的问题,请参考以下文章