Menu
CoddyTech

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 方法是一个专用的设置方法,会强制执行规则:不允许存入负数。外部代码必须通过你的方法来操作,以确保结构体始终处于有效状态。这就是封装的实际应用:隐藏数据,同时提供受控的行为。

challenge icon

挑战

简单

我们来构建一个温度转换器,通过 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 行:要设置的新华氏温度值

所有温度输出都保留两位小数。按以下顺序输出:

  1. 创建后:C: [celsius] F: [fahrenheit]
  2. 设置摄氏温度后:C: [celsius] F: [fahrenheit]
  3. 设置华氏温度后: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 值并打印结果
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Go 在线编译器