在 Scala 中,类(class) 和 对象(object) 是面向对象编程的核心概念,但它们的用途和特性有所不同。下面详细介绍它们的区别与联系:
1. 类(class)
类是创建对象的模板,定义了对象的属性和行为。与 Java 中的类类似,但 Scala 的类更加简洁灵活。
基本特性:
- 需要实例化:必须使用
new关键字创建实例 - 可带参数:类名后可直接定义参数(主构造函数)
- 可被继承:默认不可被继承,需用
open修饰(Scala 3)或加extends显式声明
示例:
// 带参数的类(主构造函数)
class Person(name: String, age: Int) {
// 方法
def introduce(): Unit = {
println(s"I'm $name, $age years old")
}
}
// 创建实例
val person = new Person("Alice", 30)
person.introduce() // 输出: I'm Alice, 30 years old
2. 对象(object)
对象是 单例实例,无需实例化,自身就是一个实例。相当于 Java 中的单例模式,但语法更简洁。
基本特性:
- 单例性:整个程序中只有一个实例
- 无需 new:直接通过对象名访问
- 不能带参数:对象定义不能有构造参数
- 可作为工具类:常用于定义工具方法、常量等
示例:
object MathUtils {
// 工具方法
def add(a: Int, b: Int): Int = a + b
def multiply(a: Int, b: Int): Int = a * b
}
// 直接使用,无需实例化
println(MathUtils.add(2, 3)) // 输出: 5
println(MathUtils.multiply(2, 3)) // 输出: 6
3. 伴生类与伴生对象
如果一个 类 和一个 对象 同名且定义在同一个文件中,它们互为 伴生类(class) 和 伴生对象(object) 。
特性:
- 可以互相访问对方的私有成员
- 伴生对象常作为类的工厂方法使用
示例:
// 伴生类
class Person private(val name: String) { // 私有构造函数
private def secret(): String = "I like Scala"
}
// 伴生对象
object Person {
// 工厂方法(替代 new 创建实例)
def apply(name: String): Person = new Person(name)
// 访问伴生类的私有方法
def getSecret(person: Person): String = person.secret()
}
// 使用伴生对象创建实例
val person = Person("Bob") // 等价于 Person.apply("Bob")
println(Person.getSecret(person)) // 输出: I like Scala
4. 类与对象的核心区别
| 特性 | 类(class) | 对象(object) |
|---|---|---|
| 实例化 | 需要用 new 创建实例 | 无需实例化,自身就是实例 |
| 构造参数 | 可以有参数(主 / 辅助构造) | 不能有参数 |
| 继承 | 可被继承(需特殊修饰) | 不能被继承 |
| 用途 | 定义实体模板 | 单例、工具类、工厂方法 |
5. 应用场景
-
类:用于定义实体(如
User、Order),需要创建多个实例时使用 -
对象:
- 工具类(如
DateUtils) - 单例服务(如
Config) - 伴生对象(为类提供工厂方法或访问私有成员)
- 程序入口(
object Main extends App { ... })
- 工具类(如
// 程序入口示例(对象作为主程序)
object Main extends App {
println("Hello, Scala!") // 直接运行,无需 main 方法
}
总结
-
类(class) :
- 是创建对象的模板,定义了对象的属性和行为
- 需要通过
new关键字实例化才能使用 - 可包含构造参数(主构造函数)和辅助构造函数
- 可被继承(Scala 3 中需用
open修饰) - 主要用于定义需要多个实例的实体(如用户、订单等)
-
对象(object) :
- 是单例实例,自身就是唯一实例,无需
new关键字 - 不能定义构造参数
- 不能被继承
- 常用于工具类、单例服务、程序入口(
extends App)等场景
- 是单例实例,自身就是唯一实例,无需
-
特殊关系:伴生类与伴生对象:
- 同名且在同一文件中的类和对象互为伴生
- 可互相访问对方的私有成员
- 伴生对象常作为类的工厂方法,简化实例创建
-
核心差异:
- 类需要实例化,对象是单例无需实例化
- 类可带构造参数,对象不能
- 类可被继承,对象不能