Scala 类和对象
在 Scala 中,类(Class)和对象(Object)是面向对象编程的核心概念,同时结合了函数式编程的特性。Scala 的类和对象设计灵活,支持封装、继承、多态等特性,并且通过伴生对象(Companion Object)实现了静态成员的功能。以下是对 Scala 类和对象的中文讲解,内容简洁清晰,涵盖定义、用法、特性及注意事项,适合初学者理解。
1. 类和对象概述
- 类(Class):
- 类的定义是创建对象的蓝图,封装了数据(字段)和行为(方法)。
- 使用
class
关键字定义,支持构造函数、继承等。 - 对象(Object):
- 对象是类的实例,或者是使用
object
关键字定义的单例对象。 - 单例对象常用于实现静态成员或程序入口。
- 特点:
- Scala 类是面向对象的,支持封装、继承、多态。
- 单例对象(
object
)是 Scala 独有的,替代 Java 的static
。 - 伴生对象:同名的类和对象在同一文件中,可以互相访问私有成员。
- 用途:类用于建模数据和行为,对象用于单例模式或静态功能。
2. 类的定义与使用
1. 基本类定义
- 语法:
class 类名(参数: 类型, ...) {
// 字段和方法
}
- 主构造函数:定义在类名后的参数列表,直接用于初始化对象。
- 示例:
class Person(name: String, age: Int) {
// 字段(由主构造函数参数自动生成)
def greet(): String = s"Hello, I'm $name, $age years old"
}
object ClassDemo {
def main(args: Array[String]): Unit = {
val p = new Person("Alice", 25)
println(p.greet()) // 输出: Hello, I'm Alice, 25 years old
println(p.name) // 输出: Alice(主构造函数参数默认生成字段)
}
}
2. 构造函数
- 主构造函数:定义在类名后,参数自动成为私有字段(加
val
或var
转为公开)。
class Person(val name: String, var age: Int) // val: 只读, var: 可读写
- 辅助构造函数:使用
def this
定义,调用主构造函数。
class Person(val name: String, var age: Int) {
def this(name: String) = this(name, 0) // 辅助构造函数
}
val p = new Person("Bob") // 使用辅助构造函数
println(p.age) // 输出: 0
3. 字段和方法
- 字段:类中的变量(
val
或var
)。 - 方法:类中的函数,使用
def
定义。
class Counter {
private var count = 0 // 私有字段
def increment(): Unit = count += 1
def getCount: Int = count
}
val c = new Counter
c.increment()
println(c.getCount) // 输出: 1
4. 继承
- 使用
extends
关键字实现继承,支持方法重写。 - 示例:
class Animal(val species: String) {
def move(): String = "Moving"
}
class Dog(name: String) extends Animal("Dog") {
override def move(): String = s"$name is running"
}
val dog = new Dog("Rex")
println(dog.move()) // 输出: Rex is running
3. 对象的定义与使用
1. 单例对象
- 使用
object
关键字定义,Scala 中没有static
,单例对象用于静态成员。 - 语法:
object 对象名 {
// 字段和方法
}
- 示例:
object Logger {
def log(message: String): Unit = println(s"Log: $message")
}
Logger.log("Hello") // 输出: Log: Hello
2. 伴生对象
- 同名的类和对象在同一文件中,称为伴生对象,可以互相访问私有成员。
- 示例:
class Person private (val name: String) {
private val secret = "Hidden"
}
object Person {
def create(name: String): Person = new Person(name)
def reveal(p: Person): String = p.secret // 访问私有成员
}
object ObjectDemo {
def main(args: Array[String]): Unit = {
val p = Person.create("Alice")
println(Person.reveal(p)) // 输出: Hidden
}
}
3. 程序入口
- Scala 程序入口通常定义在单例对象的
main
方法中:
object Main {
def main(args: Array[String]): Unit = {
println("Hello, Scala!")
}
}
4. Case Class(样例类)
- 定义:使用
case class
定义,是一种特殊的类,适合数据建模。 - 特点:
- 自动实现
toString
,equals
,hashCode
等方法。 - 主构造函数参数默认是
val
(不可变)。 - 支持模式匹配(Pattern Matching)。
- 自动生成伴生对象。
- 示例:
case class Point(x: Int, y: Int)
val p = Point(1, 2)
println(p) // 输出: Point(1,2)
println(p.x) // 输出: 1
5. 特性与注意事项
- 不可变性:
- 主构造函数参数默认私有,加
val
或var
公开。 - 推荐使用
val
和case class
实现不可变数据。 - 访问修饰符:
- 默认
public
,支持private
,protected
,private[this]
,private[package]
(详见前文)。 - 单例对象 vs 类:
- 单例对象是全局唯一的,适合工具类或配置。
- 类需要实例化,适合建模多个对象。
- Scala 2 vs Scala 3:
- Scala 3 简化了构造函数语法(如可省略
new
)。 - Scala 3 增强了
case class
的模式匹配支持。 - 性能:
- 类实例化有轻微开销,单例对象初始化一次。
case class
自动生成的方法可能增加少量开销。
6. 实践示例
综合示例,展示类、对象和样例类的用法:
// 定义类
class Person(val name: String, var age: Int) {
def greet(): String = s"Hello, I'm $name"
}
// 伴生对象
object Person {
def create(name: String, age: Int): Person = new Person(name, age)
}
// 样例类
case class Point(x: Int, y: Int)
// 主程序
object ClassObjectDemo {
def main(args: Array[String]): Unit = {
// 类实例化
val p1 = new Person("Alice", 25)
println(p1.greet()) // 输出: Hello, I'm Alice
p1.age = 26 // 修改 var 字段
println(p1.age) // 输出: 26
// 伴生对象
val p2 = Person.create("Bob", 30)
println(p2.greet()) // 输出: Hello, I'm Bob
// 样例类
val point = Point(1, 2)
println(point) // 输出: Point(1,2)
// 模式匹配
point match {
case Point(x, y) => println(s"x=$x, y=$y") // 输出: x=1, y=2
}
}
}
7. 学习建议
- 实践:在 Scala REPL(运行
scala
命令)中测试类和对象,尝试伴生对象和case class
。 - 函数式思维:优先使用
case class
和不可变字段(val
)以减少副作用。 - 模式匹配:结合
case class
学习模式匹配,增强代码表现力。 - 资源:
- 官方文档:https://www.scala-lang.org/
- Scala Exercises (https://www.scala-exercises.org/)
- 《Programming in Scala》by Martin Odersky
如果需要深入讲解某一方面(如伴生对象、继承或模式匹配)或更多示例,请告诉我!