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

导入

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

一、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 成员在类外部不可访问

三、privatethis 访问权限

定义

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

语法特点

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

示例:privatethis 的严格限制

代码

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] 在伴生对象中也不可访问

四、案例

示例:使用 privatethis 保护账户余额

代码

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. privatethis - 只允许当前对象实例访问
相关推荐
开开心心就好11 小时前
清理此电脑网盘图标工具,开源免费好用
网络·网络协议·tcp/ip·智能手机·电脑·scala·erlang
典典分享指南4 天前
用结构化数据管理产品知识库
scala·bash·batch·actionscript
Thomas21437 天前
scala 闭包
开发语言·后端·scala
江畔柳前堤7 天前
前台·中台·后台:2026年AI原生时代的架构全景图
开发语言·人工智能·算法·机器学习·架构·scala·ai-native
Thomas214315 天前
Java scala 数组 链表
java·链表·scala
江畔柳前堤17 天前
消息队列:从直觉到精通的完整认知地图
开发语言·人工智能·算法·机器学习·ruby on rails·scala
hopsky1 个月前
《Scala 学习手册》核心内容详解
人工智能·学习·scala
abcy0712131 个月前
scala playframework 搭建与新建controller教程
scala
lpfasd1231 个月前
编程语言榜单变迁分析
开发语言·后端·scala
戮漠summer2 个月前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala