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

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

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函数已正确定义。)

错误:(12,33)方法AbstractSuperClass中的类someFunction无法在AbstractSuperClass中访问 不允许访问受保护的方法someFunction,因为 前缀类型AbstractSuperClass不符合 发生访问的子类 someFunction(num)+ another.someFunction(num)

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

但是,我知道这里一定有我不明白的地方。我想知道如何更改代码以使其编译。受到赞赏。

biao12319880808 回答:受保护的方法,该方法采用抽象超类实例和“不允许访问受保护方法”错误

在scala中,受保护比在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的类型符合包含访问权限的类的type-in​​stance。

因此访问权限取决于您选择的内容。

您违反了第三个条件,第一个条件是补救方法。

本文链接:https://www.f2er.com/2818725.html

大家都在问