Menu
Coddy logo textTech

Métodos Getter y Setter

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 49 de 107.

Dado que los campos no exportados no pueden ser accedidos directamente desde fuera de un paquete, es necesario proporcionar métodos que permitan un acceso controlado. Estos son comúnmente llamados getters y setters.

En Go, la convención para los getters es sencilla: usa el nombre del campo con la primera letra en mayúscula. No uses el prefijo "Get"; simplemente usa Balance(), no GetBalance():

type BankAccount struct {
    balance int  // no exportado
}

// Getter - devuelve el valor
func (b *BankAccount) Balance() int {
    return b.balance
}

// Setter - modifica el valor con validación
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

El verdadero poder de los setters es añadir validación o lógica de negocio. En lugar de permitir que el código externo establezca cualquier valor directamente, tú controlas lo que está permitido:

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

Este método Deposit actúa como un setter especializado que impone reglas: no se permiten depósitos negativos. El código externo debe pasar a través de tus métodos, asegurando que el struct siempre permanezca en un estado válido. Esto es la encapsulación en acción: ocultar los datos mientras se expone un comportamiento controlado.

challenge icon

Desafío

Fácil

Vamos a construir un convertidor de temperatura que demuestre una encapsulación adecuada utilizando métodos getter y setter. Crearás un struct que almacena la temperatura internamente en Celsius pero proporciona acceso controlado a través de métodos con validación.

Organizarás tu código en dos archivos:

  • temperature.go: Crea un struct Temperature con un campo celsius no exportado (float64). Implementa los siguientes métodos:
    • Celsius() - un getter que devuelve la temperatura actual en Celsius
    • SetCelsius(value float64) - un setter que solo acepta valores iguales o superiores al cero absoluto (-273.15). Si el valor está por debajo de este umbral, la temperatura debe permanecer sin cambios.
    • Fahrenheit() - devuelve la temperatura convertida a Fahrenheit utilizando la fórmula: (celsius * 9/5) + 32
    • SetFahrenheit(value float64) - convierte la entrada de Fahrenheit a Celsius y la almacena, pero solo si el valor Celsius resultante es igual o superior a -273.15
    También añade un constructor NewTemperature(celsius float64) *Temperature que crea una temperatura inicializada al valor dado (asume una entrada válida para el constructor).
  • main.go: Lee los valores de temperatura de la entrada y demuestra los métodos getter/setter. Crea una temperatura, muestra sus valores en ambas unidades, luego intenta establecer nuevos valores y muestra los resultados.

Se proporcionarán las siguientes entradas:

  • Línea 1: Valor Celsius inicial
  • Línea 2: Nuevo valor Celsius a establecer
  • Línea 3: Nuevo valor Fahrenheit a establecer

Formatea todas las salidas de temperatura con dos decimales. Imprime la siguiente secuencia:

  1. Después de la creación: C: [celsius] F: [fahrenheit]
  2. Después de establecer Celsius: C: [celsius] F: [fahrenheit]
  3. Después de establecer Fahrenheit: C: [celsius] F: [fahrenheit]

Por ejemplo, dados 25, -300, y 212, tu salida debería ser:

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

Observa que la segunda línea muestra valores sin cambios porque -300 está por debajo del cero absoluto, por lo que el setter lo rechazó. La tercera línea muestra la temperatura después de establecer con éxito 212°F (que se convierte a 100°C). Este es el poder de los setters: imponen reglas que mantienen tus datos válidos.

Hoja de referencia

Los campos no exportados requieren métodos getter y setter para un acceso controlado desde fuera del paquete.

Convención de Getters

En Go, los getters utilizan el nombre del campo con la primera letra en mayúscula. No use el prefijo "Get":

type BankAccount struct {
    balance int  // unexported
}

// Getter - returns the value
func (b *BankAccount) Balance() int {
    return b.balance
}

Setter con Validación

Los setters modifican valores y pueden incluir validación o lógica de negocio:

// Setter - modifies the value with validation
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

Setters Especializados

Cree métodos que impongan reglas específicas en lugar de permitir la asignación directa de valores:

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

Este enfoque garantiza el encapsulamiento: ocultar datos mientras se expone un comportamiento controlado, manteniendo los structs en un estado válido.

Pruébalo tú mismo

package main

import (
	"fmt"
)

func main() {
	// Leer los valores de entrada
	var initialCelsius float64
	var newCelsius float64
	var newFahrenheit float64
	fmt.Scanln(&initialCelsius)
	fmt.Scanln(&newCelsius)
	fmt.Scanln(&newFahrenheit)

	// TODO: Crear una nueva Temperature usando el constructor

	// TODO: Imprimir los valores iniciales en el formato "C: [celsius] F: [fahrenheit]" con 2 decimales

	// TODO: Intentar establecer el nuevo valor de Celsius e imprimir el resultado

	// TODO: Intentar establecer el nuevo valor de Fahrenheit e imprimir el resultado
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos