scala中的访问修饰符位置说明

mai*_*gar 1 scala

我发现我们可以在类之前和类名之后使用访问修饰符。例如,我有 2 个类如下

package com.company.package.sub_package

protected class Animal1{
  def makeSound(): Unit = println("Bow ow")
}


object Animal1{
  def main(args: Array[String])
  {
    val animal = new Animal2()
    animal.makeSound()
  }
}
Run Code Online (Sandbox Code Playgroud)
package com.company.package.sub_package

class Animal2 protected{
  def makeSound(): Unit = println("Meow")
}


object Animal2{
  def main(args: Array[String])
  {
    val animal = new Animal1()
    animal.makeSound()
  }
}
Run Code Online (Sandbox Code Playgroud)

此处,Animal1 主方法中出现错误,指出无法在对象 Animal1 中访问 Animal2。

如果我扩展 Animal2 类,子类就可以访问父类。

我从中了解到的是,如果我们在类名之后写 protected,它对同一个包中的类不可用,如果我在类之前纠正它,它对包中的所有类可用,仅对它的子类可用,是这样吗?一个正确的假设?访问修饰符的位置的确切意义是什么?

Jör*_*tag 5

访问修饰符的位置的确切意义是什么?

访问修饰符总是出现在它修改其访问权限的事物之前。

在您的第一个示例中,protected出现在 class 之前Animal1,因此它规定了对 class 的访问。

在您的第二个示例中,protected位于主构造函数之前,因此它规定了对主构造函数的访问。(注意:它出现在主构造函数之前并不明显,因为它Animal2有一个空的主构造函数,但 Scala 语言规范说如果类没有参数列表,()则插入一个空参数列表。)

所以,你的Animal2班级实际上相当于

class Animal2 protected () {
  def makeSound(): Unit = println("Meow")
}
Run Code Online (Sandbox Code Playgroud)

限制访问主构造函数的一个典型原因是通过辅助构造函数或伴随模块中的工厂方法来控制实例创建。

您可以在 Scala 语言规范的5.3类定义部分中找到主构造函数的访问修饰符规范。