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 - 只允许当前对象实例访问
相关推荐
开开心心就好5 天前
用户推荐的文件解锁与强制操作工具
安全·智能手机·pdf·scala·音视频·symfony·1024程序员节
WL_Aurora6 天前
Scala核心编程(二):变量与数据类型详解
开发语言·scala
WL_Aurora7 天前
Scala核心编程(一):Scala语言概述与快速入门
spark·scala
o丁二黄o8 天前
语义版本控制:用Gemini镜像站实现合同条款的深度差异分析与风险追踪
javascript·kotlin·scala
与仪共舞11 天前
罗德与施瓦茨 NRP18S|三路二极管射频功率传感器
scala·数据库架构
howard200515 天前
1.8.3 掌握Scala类与对象 - Scala基本骨架方法
scala·基本骨架方法
howard200515 天前
1.9 掌握Scala抽象类与特质
scala·抽象类·特质
howard200516 天前
1.8.2 掌握Scala类与对象 - 单例对象与伴生对象
scala·伴生对象·单例对象
howard200518 天前
1.7.1 掌握Scala函数 - 声明Scala函数
scala·声明scala函数·显式声明·隐式声明
howard200520 天前
1.6.4 掌握Scala数据结构 - 元组
scala·元组