18scala中访问控制与方法重写

39 阅读2分钟

一. private

默认情况下,类的属性在可以通过对象.属性名的方式来获取,如果不希望在类的外部被访问,可以用private来修饰。

格式:

class 类名{

private 属性

private 方法

}

class Student(val name: String, val age: Int) {

  // private:私有访问,本类访问,本对象访问,在类里面可以访问,在类之外的地方,不能直接访问

  private val hobbies: String = "躲在被子里,看恐怖小说"

  private def hobby(): Unit = {
    println(s"${hobbies}")
  }

  def sayHi(): Unit = {
    println(s"${name}, ${age}")

    hobby() // 在类的内部,可以调用私有方法
  }

}

def main(args: Array[String]): Unit = {
    val stu = new Student("小花", 18)
    stu.sayHi()
  // println(stu.hobbies)
  // stu.hobby() // 在类的外部,无法访问私有属性
}

结果如图:

屏幕截图 2025-10-29 100500.png

二. 判断类和对象的关系

当我们拿到一个对象时,如何知道它所属的类呢?

方法1: 对象.getClass()

方法2:对象.isInstanceof[类]

class Student() {}
class Teacher() {}

def main(args: Array[String]): Unit = {

  val age: Int = 1

  val stu = new Student()
  // stu 是对像名
  // Student是类名
  // stu是Student类的实例

  // 返回类名
  println(stu.getClass) // class level02.Class03$Student
  println(age.getClass) // int

  // 注意:[] 结果是Boolean值
  println(stu.isInstanceOf[Student]) // true

  println(stu.isInstanceOf[Teacher]) // false
  
}

结果如图:

屏幕截图 2025-10-29 102508.png

三. 重写toString

1.为什么我们在打印类的对象的时候,输出的内容非常不好看?

如果我们希望改进这一点,可以通过重写toString方法来实现。

使用println来输出对象是,他会自动调用toString方法。

在Scala中,要重写一个方法,你需要使用override关键字。对于toString方法,你可以在你的类中定义它,并使用override来指明这是对父类方法的重写。

2. 定义toString方法

你可以在类的内部直接定义toString方法。这个方法通常不需要任何参数,并且返回一个String类型的结果。

// 目标:改进类的代码,让它在println输出的时候,输出的信息更友好一些!

// 重写toString方法
// (1) override 重写,覆盖...
// (2) toString 方法,是每个对象都会自带的一个方法,当我们使用println时,它就会自动被调用,返回一个字符串,就是输出的内容

class Student(var name: String, var age: Int) {

  override def toString: String = s"姓名:${name}"
}

def main(args: Array[String]): Unit = {

  val stu1 = new Student("小芯", 18) // level02.Class04$Student@235c8f8
  val stu2 = new Student("小明", 18) // level02.Class04$Student@133c58f

  println(stu1)
  println(stu2)
}

结果如图:

屏幕截图 2025-10-29 103751.png

四. 判断两个对象是相等的?

两个对象做比较==时,会自动调用equals方法。我们可以重写equals方法,并自己定义两个对象相等的标准。

[提问]如何判断两个对象在业务上是相等的?

// 目标:判断两个Student对象是否相等的依据是:学号相同 并且 姓名相同
//      这里的判断条件可以自己来确定

class Student(val id: String, val name: String, val age: Int) {

  // 改写 equals 方法
  // 在使用 == 判断的时候,会自动调用。
  //    如果返回true,则相等
  //    如果返回false,则不相等

  override def equals(obj: Any): Boolean = {
    println(s"比较是否相等..... ${this.id},${this.name},")

    // 在这里写自己判断逻辑
    // 把obj当做Student

    val other = obj.asInstanceOf[Student]

    this.id == other.id && this.name == other.name
  }
}

def main(args: Array[String]): Unit = {

  val stu1 = new Student("2024101001", "小花", 18)
  val stu2 = new Student("2024101001", "小花", 19)

  if (stu1 == stu2) {
    println("他们是同一个人")
  } else {
    println("不是同一个人")
  }

  // println(stu1 == stu2) // false
}

结果如图:

屏幕截图 2025-10-29 111720.png