【问题标题】: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 实例的受保护字段,但从我的角度来看,它在这里应该没有问题,因为 SubclassSquareAbstractSuperClass 的子类。

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

【问题讨论】:

  • 您似乎无法访问另一个实例上的protected 字段。但是,这对我来说似乎是一个错误。
  • 是的,通常你可以访问另一个对象的受保护字段,只要它们都是同一个类的实例。从技术上讲,参数anotherthis 都是AbstractSuperClass 的实例,所以人们会认为它有效,但显然不是。
  • 开场截击加一个,或者如果你愿意,莎莉。我希望他们为错误跟踪器添加一个模板,开头是:“我设计了一个相当简单的例子来说明我的观点,如下所示。”

标签: scala protected


【解决方案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)
      }
    

    【讨论】:

      猜你喜欢
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      相关资源
      最近更新 更多