Getter 和 Setter 方法
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 49 课,共 107 课。
由于无法从包外部直接访问未导出的字段,你需要提供方法来实现受控访问。这些方法通常称为获取方法和设置方法。
在 Go 中,getter 的惯例很简单:使用首字母大写的字段名。不要加上“Get”前缀,只用 Balance(),不要用 GetBalance():
type BankAccount struct {
balance int // 未导出
}
// Getter:返回值
func (b *BankAccount) Balance() int {
return b.balance
}
// Setter:验证后修改值
func (b *BankAccount) SetBalance(amount int) {
if amount >= 0 {
b.balance = amount
}
}
setter 方法的真正作用是添加验证或业务逻辑。你可以控制允许设置的值,而不是让外部代码直接设置任意值:
func (b *BankAccount) Deposit(amount int) bool {
if amount <= 0 {
return false
}
b.balance += amount
return true
}
这个 Deposit 方法是一个专用的设置方法,会强制执行规则:不允许存入负数。外部代码必须通过你的方法来操作,以确保结构体始终处于有效状态。这就是封装的实际应用:隐藏数据,同时提供受控的行为。
挑战
简单我们来构建一个温度转换器,通过 getter 和 setter 方法演示正确的封装。你将创建一个结构体,在内部以摄氏度存储温度,并通过带有验证的方法对其进行受控访问。
你将把代码分成两个文件:
temperature.go:创建一个Temperature结构体,其中包含未导出的celsius字段(float64)。实现以下方法:Celsius()- getter,返回当前的摄氏温度SetCelsius(value float64)- setter,只接受大于或等于绝对零度(-273.15)的值。如果值低于此阈值,温度应保持不变。Fahrenheit()- 使用公式(celsius * 9/5) + 32将温度转换为华氏度并返回SetFahrenheit(value float64)- 将输入的华氏温度转换为摄氏度并存储,但只有转换后的摄氏温度大于或等于 -273.15 时才存储
NewTemperature(celsius float64) *Temperature,创建一个以给定值初始化的温度(假设构造函数的输入有效)。main.go:从输入中读取温度值,并演示 getter 和 setter 方法。创建一个温度,显示它的两种单位值,然后尝试设置新值并显示结果。
将提供以下输入:
- 第 1 行:初始摄氏温度值
- 第 2 行:要设置的新摄氏温度值
- 第 3 行:要设置的新华氏温度值
所有温度输出都保留两位小数。按以下顺序输出:
- 创建后:
C: [celsius] F: [fahrenheit] - 设置摄氏温度后:
C: [celsius] F: [fahrenheit] - 设置华氏温度后:
C: [celsius] F: [fahrenheit]
例如,给定 25、-300 和 212,输出应为:
C: 25.00 F: 77.00
C: 25.00 F: 77.00
C: 100.00 F: 212.00注意,第二行的值没有变化,因为 -300 低于绝对零度,所以 setter 拒绝了这个值。第三行显示成功设置 212°F 后的温度(转换后为 100°C)。这就是 setter 的作用。它们会强制执行规则,确保数据有效。
亲手试试
package main
import (
"fmt"
)
func main() {
// 读取输入值
var initialCelsius float64
var newCelsius float64
var newFahrenheit float64
fmt.Scanln(&initialCelsius)
fmt.Scanln(&newCelsius)
fmt.Scanln(&newFahrenheit)
// TODO:使用构造函数创建一个新的 Temperature 对象
// TODO:按 "C: [celsius] F: [fahrenheit]" 的格式打印初始值,保留 2 位小数
// TODO:尝试设置新的 Celsius 值并打印结果
// TODO:尝试设置新的 Fahrenheit 值并打印结果
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Go 在线编译器