📜  斯卡拉 |控制构造函数字段的可见性(1)

📅  最后修改于: 2023-12-03 15:26:14.382000             🧑  作者: Mango

斯卡拉 | 控制构造函数字段的可见性

在斯卡拉中,我们可以通过访问修饰符来控制构造函数字段的可见性。具体来说,我们可以将字段定义为 privateprotected,以便构造函数之外的代码不能访问它们。

private字段

如果字段被定义为 private,则它只能从当前类的构造函数中进行访问。这意味着它不能从类之外的任何代码中访问。例如,以下代码定义了一个名为 Person 的类,其中 nameage 字段都是 private

class Person(private val name: String, private val age: Int) {
  def introduce(): Unit = {
    println(s"My name is $name and I am $age years old.")
  }
}

在这里,nameage 字段可以通过类中 introduce 方法的访问进行访问。但是,我们无法从类之外的任何代码中访问这些字段:

val alice = new Person("Alice", 25)

// 编译错误:value name is not a member of Person
println(alice.name)
protected字段

如果字段被定义为 protected,则它可以从当前类的构造函数和继承类的成员方法中进行访问。这意味着它不能从类之外的任何代码中访问,也不能从子类之外的任何代码中访问。

例如,以下代码定义了一个名为 Employee 的类,它继承自 Person 类并添加了一个名为 salaryprotected 字段:

class Employee(name: String, age: Int, protected val salary: Double)
  extends Person(name, age) {

  def printSalary(): Unit = {
    println(s"My salary is $salary dollars.")
  }
}

在这里,salary 字段可以从 Employee 类的成员方法 printSalary 中访问。同时,我们无法从类之外或子类之外的任何代码中访问该字段:

val bob = new Employee("Bob", 30, 50000.0)

// 编译错误:value salary is not a member of Employee
println(bob.salary)
继承和字段可见性

需要注意的是,在子类中继承父类的字段时,其可见性不能更严格。例如,如果父类中的字段是 private,则子类中的相应字段也必须是 private。如果子类中的相应字段是 protected,则父类中的字段可以是 protectedpublic

class A(private val x: Int)

// 编译错误:overriding variable x in class A cannot reduce access privileges
class B extends A(0) {
  override protected val x: Int = 1
}

在上面的代码中,A 类中的字段 xprivate 的,因此 B 类中不能出现更宽松的可见性。将 B 类中的 x 字段定义为 protected 将导致编译错误。

结论

通过访问修饰符,我们可以控制在构造函数之外的代码是否可以访问类的字段。私有字段只能在当前类的构造函数中访问,而受保护字段可以在当前类和继承类的成员方法中访问。我们必须考虑子类和父类中字段的可见性,以确保继承关系正确地维护。