Menu
Coddy logo textTech

Геттеры и сеттеры

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 49 из 107.

Поскольку к неэкспортируемым полям нельзя получить прямой доступ извне package, необходимо предоставить методы, которые обеспечивают контролируемый доступ. Обычно их называют геттерами и сеттерами.

В Go соглашение для геттеров простое: используйте имя поля с заглавной первой буквой. Не добавляйте префикс «Get», просто используйте Balance(), а не GetBalance():

type BankAccount struct {
    balance int  // неэкспортируемый
}

// Геттер - возвращает значение
func (b *BankAccount) Balance() int {
    return b.balance
}

// Сеттер - изменяет значение с валидацией
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

Настоящая сила сеттеров заключается в добавлении проверки или бизнес-логики. Вместо того чтобы позволять внешнему коду напрямую устанавливать любое значение, вы контролируете, что разрешено:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

Этот метод Deposit действует как специализированный сеттер, который обеспечивает соблюдение правил: отрицательные депозиты не допускаются. Внешний код должен обращаться к вашим методам, благодаря чему структура всегда остаётся в допустимом состоянии. Это инкапсуляция в действии: данные скрыты, а контролируемое поведение предоставлено.

challenge icon

Задание

Легко

Давайте создадим конвертер температуры, демонстрирующий правильную инкапсуляцию с использованием методов getter и setter. Вы создадите структуру, которая хранит температуру внутри в Celsius, но предоставляет контролируемый доступ через методы с проверкой.

Вы организуете код в двух файлах:

  • temperature.go: Create структуру Temperature с неэкспортируемым полем celsius (float64). Implement следующие методы:
    • Celsius() — getter, возвращающий current температуру в Celsius
    • SetCelsius(value float64) — setter, который принимает Only значения, равные absolute нулю или превышающие его (-273.15). Если значение ниже этого порога, температура должна остаться без изменений.
    • Fahrenheit() — возвращает температуру, converted в Fahrenheit с использованием Formula: (celsius * 9/5) + 32
    • SetFahrenheit(value float64) — converts input из Fahrenheit в Celsius и сохраняет его, но Only если resulting значение Celsius равно -273.15 или превышает его
    Также добавьте constructor NewTemperature(celsius float64) *Temperature, который creates температуру, initialized заданным значением (считайте input для constructor корректным).
  • main.go: Считайте значения температуры из input и продемонстрируйте методы getter/setter. Create температуру, отобразите её значения в обеих единицах, затем попытайтесь установить новые значения и покажите resulting результаты.

Будут предоставлены следующие input:

  • Строка 1: Initial значение Celsius
  • Строка 2: Новое значение Celsius для установки
  • Строка 3: Новое значение Fahrenheit для установки

Отформатируйте все значения температуры с двумя десятичными знаками. Print следующую последовательность:

  1. После создания: C: [celsius] F: [fahrenheit]
  2. После установки Celsius: C: [celsius] F: [fahrenheit]
  3. После установки Fahrenheit: C: [celsius] F: [fahrenheit]

Например, если given значения 25, -300 и 212, ваш output должен быть:

C: 25.00 F: 77.00
C: 25.00 F: 77.00
C: 100.00 F: 212.00

Обратите внимание, что во второй строке показаны unchanged значения, потому что -300 ниже absolute нуля, поэтому setter отклонил это значение. В третьей строке показана температура после успешной установки 212°F (что converts в 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