diegoRodicio

View Categories

⚙️ Métodos, getters/setters e privacidade

Os métodos son funcións que pertencen a unha clase. Xa coñecemos os parámetros e os retornos polo Tema 2.1; aquí aplicámolos aos obxectos.

⚙️ Métodos de instancia

Traballan cun obxecto concreto. Por exemplo, alumno.actualizarNota(8) cambia a nota dese alumno, non a dos demais.

Poden recibir parámetros e devolver valores. Un método declarado con void non proporciona un resultado para usar noutra expresión.

📦 Métodos estáticos

Levan static e chámanse co nome da clase, sen crear un obxecto. Non poden usar this porque non pertencen a un obxecto concreto.

class UtilidadesNotas {
  // Non necesita crear un obxecto UtilidadesNotas.
  static double media(double primeira, double segunda) {
    return (primeira + segunda) / 2;
  }
}

void main() {
  print(UtilidadesNotas.media(6, 8)); // 7.0
}

🔒 Atributos privados

Un atributo que comeza por _ é privado: normalmente, só se pode usar desde o mesmo ficheiro Dart, mesmo desde outra clase dese ficheiro.

Ao escribir alumno.nota, accedemos a unha propiedade: pode ser un atributo ou usar un getter para ler o valor e un setter para cambialo.

Por exemplo, podemos facer que a nota só admita valores entre 0 e 10:

class Alumno {
  int _nota = 0;

  int get nota => _nota;

  set nota(int valor) {
    if (valor >= 0 && valor <= 10) {
      _nota = valor;
    }
  }
}

void main() {
  final alumno = Alumno();

  alumno.nota = 8;
  print(alumno.nota); // 8

  alumno.nota = 15; // Non se modifica porque non é unha nota válida
  print(alumno.nota); // 8
}

📥 Getters e setters

En Dart, os getters e setters úsanse como se accedésemos directamente a unha propiedade.

💡 Sen parénteses nin métodos como getNota() ou setNota(8):

  • Un getter permite ler un valor: alumno.nota.
  • Un setter permite asignalo: alumno.nota = 8.

📌 Aínda que cada variable de instancia ten un getter e un setter implícitos (se non é unha variable final), podes definir os teus propios getters e setters usando as palabras clave get e set.

Son útiles para:

  • Engadir lóxica personalizada ao ler ou escribir unha propiedade (validación, transformación, etc.).
  • Expor unha propiedade de forma controlada sen dar acceso directo á variable de instancia.
  • Calcular un valor dinamicamente ao ser accedido.
class Rectangulo {
  double _lonxitude; // Variábel de instancia privada
  double _largura;   // Variábel de instancia privada

  Rectangulo(this._lonxitude, this._largura);

  // Getter explícito para 'area' (valor calculado)
  double get area {
    return _lonxitude * _largura;
  }

  // Setter explícito para 'lonxitude' (con validación)
  set lonxitude(double novaLonxitude) {
    if (novaLonxitude <= 0) {
      throw ArgumentError('A lonxitude debe ser positiva.');
    }
    _lonxitude = novaLonxitude;
  }

  // Getter explícito para 'lonxitude' (acceso controlado á propiedade privada)
  double get lonxitude => _lonxitude; // Sintaxe abreviada
}

void main() {
  var r = Rectangulo(10.0, 5.0);

  print('Lonxitude inicial: ${r.lonxitude}'); // Accede ao getter 'lonxitude'
  print('Área inicial: ${r.area}');           // Accede ao getter 'area'

  r.lonxitude = 12.0; // Usa o setter 'lonxitude'
  print('Nova lonxitude: ${r.lonxitude}');
  print('Nova área: ${r.area}');

  try {
    r.lonxitude = -2.0; // Intenta asignar un valor inválido
  } catch (e) {
    print('Erro ao establecer lonxitude: $e');
  }
}

➕ Sobrecarga de operadores

Dart permite definir como funcionan operadores como + cos obxectos dunha clase. Facémolo cun método de instancia que leva a palabra operator. Neste exemplo, sumar dúas carteiras crea outra co total de euros.

class Carteira {
  int euros;

  Carteira(this.euros);

  // Sumamos os euros das dúas carteiras.
  Carteira operator +(Carteira outra) {
    return Carteira(euros + outra.euros);
  }
}

void main() {
  var carteira1 = Carteira(20);
  var carteira2 = Carteira(10);

  var total = carteira1 + carteira2;

  print(total.euros); // 30
}

🧪 Exemplo completo: a nota dunha alumna

🔗 Ver o código en DartPad — https://dartpad.dev/?id=f4c0218fa3b792964c2c16097af86ec1

📌 Dentro deste ficheiro poderiamos acceder a _nota. Usamos a propiedade nota para pasar pola comprobación do setter. Esta forma de organizar os datos tamén aparecerá nos modelos de estado de Flutter.