采用抽象超类实例的受保护方法,并且出现“不允许访问受保护方法”错误

问题描述 投票:4回答:2

我设计了一个相当简单的示例,以说明我的观点,如下所示:

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不符合发生访问的子类someFunction(num)+ another.someFunction(num)

方法addition引起了问题。该代码尝试访问AbstractSuperClass实例的受保护字段,但是从我的角度来看,由于SubclassSquareAbstractSuperClass的子类,因此在这里不会造成任何问题。

但是,我知道这里肯定有些不明白的地方。我想知道如何更改代码以使其编译。非常感谢。

[我设计了一个相当简单的示例,以说明我的观点,如下所示:抽象类AbstractSuperClass { [

在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) }

您可以扩大访问范围:
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的类型符合包含访问的类的类型实例。

所以访问权限取决于您从中选择什么。

您违反了第三个条件,第一个条件是补救措施。

scala protected
2个回答
4
投票

如果受保护的成员没有资格(即,其仅受保护)然后在将类声明为声明类以及将this声明为类和子类。


3
投票
© www.soinside.com 2019 - 2024. All rights reserved.