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] - 只允许当前对象实例访问
相关推荐
ZHOUZAIHUI3 天前
WSL(Ubuntu24.04) 安装PostgreSQL
开发语言·后端·scala
chde2Wang3 天前
运行scala文件报错xsbt.CompilerInterface
bug·scala
零碎岛117 天前
scala中trait基本使用
scala
lucky_syq15 天前
Scala与Spark算子:大数据处理的黄金搭档
开发语言·spark·scala
深兰科技17 天前
廊坊市市长刘媛率队到访深兰科技,推动机器人制造基地与产业投资落地
人工智能·科技·机器人·scala·symfony·深兰科技·廊坊市市长刘媛
萧霍21 天前
判断两个对象是相等的
scala
程序员小羊!23 天前
Flink(用Scala版本写Word Count 出现假报错情况解决方案)假报错,一直显示红色报错
flink·word·scala
17311 个月前
scala中访问控制与方法重写
scala
张较瘦_1 个月前
[论文阅读] 从 5MB 到 1.6GB 数据:Java/Scala/Python 在 Spark 中的性能表现全解析
java·python·scala