Menu
Coddy logo textTech

La convención del prefijo _

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 31 de 110.

El prefijo de guion bajo _ es la forma en que Dart marca los miembros como privados. A diferencia de los lenguajes que utilizan palabras clave como private, Dart se basa en esta convención de nomenclatura para controlar la visibilidad.

Puedes aplicar el guion bajo tanto a campos como a métodos:

class Counter {
  int _count = 0;        // Campo privado
  
  void _increment() {    // Método privado
    _count++;
  }
  
  void increase() {      // Método público
    _increment();
    print('Count: $_count');
  }
}

El guion bajo funciona para cualquier identificador: variables, métodos, getters, setters e incluso nombres de clases. Una clase llamada _Helper sería privada para su biblioteca.

class Person {
  String _name;          // Privado
  int _age;              // Privado
  
  Person(this._name, this._age);
  
  String get name => _name;           // Getter público
  void _validateAge(int age) { }      // Método privado
}

Dentro de la misma clase, accedes a los miembros privados con normalidad. La restricción solo se aplica al código fuera de la librería. Esta convención deja claro de inmediato al leer el código qué miembros están destinados únicamente para uso interno: cualquier cosa que comience con _ es un detalle de implementación.

challenge icon

Desafío

Fácil

Vamos a construir un rastreador de puntuación para un juego que demuestre cómo el prefijo de guion bajo mantiene ocultos los detalles de implementación interna mientras expone una interfaz pública limpia.

Organizarás tu código en dos archivos:

  • score_tracker.dart: Crea una clase ScoreTracker que gestione la puntuación de un jugador con la encapsulación adecuada. La clase debe tener:
    • Un String playerName público: todos pueden ver quién está jugando
    • Un int _score privado inicializado en 0: la puntuación bruta debe estar protegida
    • Un int _bonusMultiplier privado inicializado en 1: esta es una mecánica interna del juego
    • Un constructor que reciba el nombre del jugador
    • Un getter público score que devuelva el _score privado
    • Un método privado _applyBonus(int points) que devuelva points * _bonusMultiplier
    • Un método público addPoints(int points) que use _applyBonus internamente para calcular los puntos reales añadidos, actualice _score e imprima Added [calculated] points!
    • Un método público activateDoubleBonus() que establezca _bonusMultiplier en 2 e imprima Double bonus activated!
    • Un método público displayStats() que muestre el estado actual del jugador
  • main.dart: Importa tu rastreador de puntuación y simula una sesión de juego:
    • Crea un ScoreTracker para el jugador 'Alex'
    • Llama a displayStats()
    • Añade 10 puntos
    • Añade 25 puntos
    • Activa el bono doble
    • Añade 15 puntos (esto debería duplicarse)
    • Llama a displayStats()
    • Imprime Final score: [score] usando el getter público

El método displayStats() debe imprimir en este formato:

=== Player Stats ===
Player: [playerName]
Current Score: [_score]

Observa cómo el método privado _applyBonus y el campo _bonusMultiplier manejan el cálculo del bono internamente. El código externo solo ve los métodos públicos y no tiene idea del sistema de multiplicadores; ese es un detalle de implementación oculto tras la convención del guion bajo.

Salida esperada:

=== Player Stats ===
Player: Alex
Current Score: 0
Added 10 points!
Added 25 points!
Double bonus activated!
Added 30 points!
=== Player Stats ===
Player: Alex
Current Score: 65
Final score: 65

Hoja de referencia

El prefijo de guion bajo _ marca los miembros como privados en Dart. Esta convención de nomenclatura controla la visibilidad sin usar palabras clave como private.

Aplica el guion bajo a campos y métodos:

class Counter {
  int _count = 0;        // Campo privado
  
  void _increment() {    // Método privado
    _count++;
  }
  
  void increase() {      // Método público
    _increment();
    print('Count: $_count');
  }
}

El guion bajo funciona para cualquier identificador: variables, métodos, getters, setters y nombres de clases:

class Person {
  String _name;          // Privado
  int _age;              // Privado
  
  Person(this._name, this._age);
  
  String get name => _name;           // Getter público
  void _validateAge(int age) { }      // Método privado
}

Los miembros privados son accesibles dentro de la misma clase, pero están restringidos para el código fuera de la librería. Cualquier cosa que comience con _ es un detalle de implementación.

Pruébalo tú mismo

import 'score_tracker.dart';

void main() {
  // TODO: Crear un ScoreTracker para el jugador 'Alex'
  
  // TODO: Llamar a displayStats()
  
  // TODO: Añadir 10 puntos
  
  // TODO: Añadir 25 puntos
  
  // TODO: Activar el bono doble
  
  // TODO: Añadir 15 puntos (esto debería duplicarse)
  
  // TODO: Llamar a displayStats()
  
  // TODO: Imprimir 'Final score: [score]' usando el getter público
}
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