Menu
Coddy logo textTech

Profundidad en Getters y Setters

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 33 de 110.

Los getters y setters se convierten en herramientas poderosas para la encapsulación cuando se combinan con campos privados. Permiten exponer una interfaz pública limpia mientras se mantiene el control total sobre cómo se accede y se modifican los datos.

Un patrón común es combinar un campo privado con un getter público y un setter que incluye validación:

class Temperature {
  double _celsius = 0;
  
  double get celsius => _celsius;
  
  set celsius(double value) {
    if (value < -273.15) {
      _celsius = -273.15;  // Mínimo del cero absoluto
    } else {
      _celsius = value;
    }
  }
}

Los setters pueden aplicar reglas de negocio, asegurando que su objeto nunca entre en un estado no válido.

También puedes crear getters calculados que derivan valores a partir de datos privados:

class Rectangle {
  double _width;
  double _height;
  
  Rectangle(this._width, this._height);
  
  double get area => _width * _height;      // Computed
  double get perimeter => 2 * (_width + _height);
  
  double get width => _width;
  set width(double value) {
    if (value > 0) _width = value;
  }
}

A veces quieres acceso de solo lectura. Simplemente proporciona un getter sin un setter:

class Order {
  final DateTime _createdAt = DateTime.now();
  
  DateTime get createdAt => _createdAt;  // Solo lectura
}

Este patrón proporciona al código externo visibilidad de los datos mientras evita cualquier modificación: el campo privado combinado con solo un getter crea un verdadero acceso de solo lectura.

challenge icon

Desafío

Fácil

Construyamos un sistema de inventario de productos que muestre el poder de los getters y setters para controlar el acceso a los datos. Crearás una clase que proteja sus datos internos y, al mismo tiempo, proporcione propiedades calculadas y validación.

Organizarás tu código en dos archivos:

  • product.dart: Define una clase Product que administre el inventario con una encapsulación adecuada. Tu producto debe tener:
    • Un String name público
    • Un double _price privado
    • Un int _quantity privado
    • Un constructor que reciba los tres valores
    • Un getter price que devuelva el precio privado
    • Un setter price que solo acepte valores mayores que 0 (ignora los valores no válidos)
    • Un getter quantity que devuelva la cantidad privada
    • Un setter quantity que solo acepte valores de 0 o mayores (ignora los valores negativos)
    • Un getter calculado totalValue que devuelva _price * _quantity
    • Un getter calculado isInStock que devuelva true si la cantidad es mayor que 0
    • Un getter de solo lectura sku que genere un SKU simple devolviendo los primeros 3 caracteres del nombre en mayúsculas, seguidos de la cantidad (por ejemplo, LAP25 para "Laptop" con una cantidad de 25)
    • Un método displayProduct() que muestre los detalles del producto
  • main.dart: Importa tu clase de producto y demuestra cómo los getters y setters controlan el acceso:
    • Crea un producto llamado 'Laptop' con un precio de 999.99 y una cantidad de 25
    • Llama a displayProduct()
    • Imprime In stock: [isInStock]
    • Imprime SKU: [sku]
    • Intenta establecer el precio en -50.0 (debe ignorarse)
    • Establece el precio en 899.99 (cambio válido)
    • Intenta establecer la cantidad en -10 (debe ignorarse)
    • Establece la cantidad en 0 (cambio válido)
    • Llama a displayProduct()
    • Imprime In stock: [isInStock]
    • Imprime SKU: [sku]

El método displayProduct() debe imprimir con este formato:

--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]

Salida esperada:

--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0

Pruébalo tú mismo

import 'product.dart';

void main() {
  // TODO: Crear un producto llamado 'Laptop' con precio 999.99 y cantidad 25

  // TODO: Llamar a displayProduct()

  // TODO: Imprimir "In stock: [isInStock]"

  // TODO: Imprimir "SKU: [sku]"

  // TODO: Intentar establecer el precio a -50.0 (debe ser ignorado)

  // TODO: Establecer el precio a 899.99 (cambio válido)

  // TODO: Intentar establecer la cantidad a -10 (debe ser ignorado)

  // TODO: Establecer la cantidad a 0 (cambio válido)

  // TODO: Llamar a displayProduct()

  // TODO: Imprimir "In stock: [isInStock]"

  // TODO: Imprimir "SKU: [sku]"
}
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

Practica por tu cuenta: Compilador de Dart online