Scala 访问权限详解:private、protected 与 private

导入

在 Scala 面向对象编程中,访问权限控制是封装性的重要体现。通过合理的访问权限设置,可以保护类的内部状态,提高代码的安全性和可维护性。本文将详细讲解 Scala 中的三种主要访问权限:private、protected 和 private[this],并通过具体代码示例展示它们的使用场景和区别。

一、private 访问权限

定义

private 是 Scala 中最严格的访问权限修饰符,用于限制成员只能在特定范围内访问。

语法特点

  • 在类的内部可以访问
  • 在类的外部不能访问
  • 在伴生对象中可以访问

示例:private 基本使用

代码

scala 复制代码
package level02

object base3101 {

  class Student(var name: String, private var age: Int) {
    def say(): Unit = {
      println(s"${this.age}") //(1)在类的内部可以访问。
    }
  }

  object Student {
    def test(student: Student): Unit = {
      println(student.age) //(3)在伴生对象中可以访问。
    }
  }

  def main(args: Array[String]): Unit = {
    val s1 = new Student("小花", 18)
    s1.say()
    // println(s1.age) // 报错。(2)在类的外部不能访问。
    Student.test(s1)
  }
}

结果展示

复制代码
18
18

代码分析

  • Student 类的 say 方法中,可以直接访问 private var age,体现了"在类的内部可以访问"
  • main 方法中,注释掉的 println(s1.age) 会编译报错,体现了"在类的外部不能访问"
  • 在伴生对象 Studenttest 方法中,可以访问 student.age,体现了"在伴生对象中可以访问"

二、protected 访问权限

定义

protected 访问权限比 private 稍宽松,除了具备 private 的访问特性外,还允许在子类中访问。

语法特点

  • 在类的内部可以访问
  • 在类的外部不能访问
  • 在伴生对象中可以访问
  • 在子类中可以访问(与 private 的主要区别)

示例:protected 与继承

代码

scala 复制代码
package level02

object base3102 {

  class Student(var name: String, private var age: Int, protected var weight: Int) {
    def say(): Unit = {
      println(s"${this.age}, ${this.weight}") //(1)在类的内部可以访问。
    }

    private def sayAge():Unit = {println(age)}

    protected def sayWeight():Unit = { println(weight) }
  }
  
  object Student {
    def test(student: Student): Unit = {
      println(student.weight) //(3)在伴生对象中可以访问。
    }
  }

  class Major(name: String, age: Int, weight: Int) extends Student(name, age, weight) {
    // 在子类中通过 super来访问父类
    // sayAge()  // 报错(4)private修饰的,在子类中无法访问。
    sayWeight() // 正常(4)protected修饰的,在子类中可以访问。
  }

  def main(args: Array[String]): Unit = {
    val s1 = new Student("小花", 18, 100)
    s1.say()
    // println(s1.weight) // 报错。(2)在类的外部不能访问。
    Student.test(s1)
  }
}

结果展示

复制代码
18, 100
100

代码分析

  • Student 类中有 private 的 age、protected 的 weightsayWeight 方法
  • Major 子类中,sayAge() 调用会报错,因为 private 成员在子类中不可访问
  • sayWeight() 调用正常执行,因为 protected 成员在子类中可以访问
  • main 方法中直接访问 s1.weight 会报错,体现了 protected 成员在类外部不可访问

三、private[this] 访问权限

定义

private[this] 是 Scala 中最严格的访问权限,限制了成员只能在当前对象实例中访问。

语法特点

  • 在类的内部可以访问
  • 在类的外部不能访问
  • 在伴生对象中不能访问
  • 在子类中不能访问

示例:private[this] 的严格限制

代码

scala 复制代码
package level02

object base3103 {

  class Student(var name: String, private var age: Int, protected var weight: Int) {
    private[this] var pwd = 123 // 密码
  }

  object Student {
    def test(student: Student): Unit = {
      println(student.age)     // 普通的private在伴生对象中可以访问
      // println(student.pwd) 报错 (3)在伴生对象中,不能访问private[this]
    }
  }

  def main(args: Array[String]): Unit = {
    val s1 = new Student("小花", 18, 100)
    Student.test(s1)
  }
}

结果展示

复制代码
18

代码分析

  • pwd 字段使用 private[this] 修饰,只能在当前对象实例中访问
  • 在伴生对象 Studenttest 方法中,可以访问普通的 private var age
  • 但访问 student.pwd 会编译报错,体现了 private[this] 在伴生对象中也不可访问

四、案例

示例:使用 private[this] 保护账户余额

代码

scala 复制代码
package level02

object class18 {

  class Bank(private[this] var balance: Double) {
    // 存钱
    def deposit(amount: Double): Unit = {
      balance += amount
    }
    // 取
    def withdraw(amount: Double): Unit = {
      if (balance >= amount) {
        balance -= amount
      }
    }

    def getBalance(): Double = balance
  }

  object Bank {
    def clear(bank: Bank): Unit = {
      // bank.balance = 0 // 在第11行,添加了private[this] 之后,就不能再直接访问balance属性
    }
  }

  def main(args: Array[String]): Unit = {
    val bank = new Bank(100)

    bank.deposit(1000)
    bank.withdraw(200)

    Bank.clear(bank)
    println(bank.getBalance())
  }
}

结果展示

复制代码
900

代码分析*

  • Bank 类的 balance 使用 private[this] 修饰,确保余额只能在当前对象实例中访问
  • 通过公共方法 depositwithdrawgetBalance 来安全地操作和查询余额
  • 在伴生对象 Bankclear 方法中,直接设置 bank.balance = 0 会编译报错
  • 这种设计确保了账户余额的安全性,防止外部直接修改

总结

Scala 提供了多层次的访问权限控制,从宽松到严格依次为:

  1. protected - 允许类内部、伴生对象和子类访问
  2. private - 允许类内部和伴生对象访问
  3. private[this] - 只允许当前对象实例访问
相关推荐
顧棟3 天前
JAVA、SCALA 与尾递归
java·开发语言·scala
深兰科技3 天前
坦桑尼亚与新加坡代表团到访深兰科技,促进AI在多领域的应用落地
java·人工智能·typescript·scala·perl·ai大模型·深兰科技
a程序小傲4 天前
scala中的Array
开发语言·后端·scala
kk哥88994 天前
scala 介绍
开发语言·后端·scala
17315 天前
scala中的Array
scala
满山狗尾草6 天前
map的常规操作
scala
渣渣盟7 天前
Flink实时数据写入Redis实战
大数据·scala·apache
pale_moonlight7 天前
十、Scala应用实践(下)
linux·开发语言·scala
云岫1158 天前
高贵的hasNext带着“迭代器”袭击你的大脑
scala
卓码软件测评10 天前
第三方软件测试评测机构:【基于Scala DSL的Gatling脚本开发:从零开始构建首个负载测试模型】
后端·测试工具·测试用例·scala·负载均衡·压力测试