A Convenção do Prefixo _
Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 31 de 110.
O prefixo de sublinhado _ é a maneira do Dart de marcar membros como privados. Ao contrário de linguagens que usam palavras-chave como private, o Dart depende desta convenção de nomenclatura para controlar a visibilidade.
Você pode aplicar o sublinhado tanto a campos quanto 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');
}
}O sublinhado funciona para qualquer identificador - variáveis, métodos, getters, setters e até nomes de classes. Uma classe chamada _Helper seria privada para sua biblioteca.
class Person {
String _name; // Private
int _age; // Private
Person(this._name, this._age);
String get name => _name; // Public getter
void _validateAge(int age) { } // Private method
}Dentro da mesma classe, você acessa membros privados normalmente. A restrição se aplica apenas ao código fora da biblioteca. Essa convenção torna imediatamente claro, ao ler o código, quais membros são destinados apenas para uso interno — qualquer coisa que comece com _ é um detalhe de implementação.
Desafio
FácilVamos construir um rastreador de pontuação para um jogo que demonstra como o prefixo de sublinhado mantém os detalhes da implementação interna ocultos, enquanto expõe uma interface pública limpa.
Você organizará seu código em dois arquivos:
score_tracker.dart: Crie uma classeScoreTrackerque gerencia a pontuação de um jogador com o encapsulamento adequado. A classe deve ter:- Um
String playerNamepúblico - todos podem ver quem está jogando - Um
int _scoreprivado inicializado como0- a pontuação bruta deve ser protegida - Um
int _bonusMultiplierprivado inicializado como1- esta é uma mecânica interna do jogo - Um construtor que recebe o nome do jogador
- Um getter público
scoreque retorna o_scoreprivado - Um método privado
_applyBonus(int points)que retornapoints * _bonusMultiplier - Um método público
addPoints(int points)que usa_applyBonusinternamente para calcular os pontos reais adicionados, atualiza_scoree imprimeAdded [calculated] points! - Um método público
activateDoubleBonus()que define_bonusMultipliercomo2e imprimeDouble bonus activated! - Um método público
displayStats()que mostra o status atual do jogador
- Um
main.dart: Importe seu rastreador de pontuação e simule uma sessão de jogo:- Crie um
ScoreTrackerpara o jogador'Alex' - Chame
displayStats() - Adicione
10pontos - Adicione
25pontos - Ative o bônus duplo
- Adicione
15pontos (isso deve ser dobrado) - Chame
displayStats() - Imprima
Final score: [score]usando o getter público
- Crie um
O método displayStats() deve imprimir neste formato:
=== Player Stats ===
Player: [playerName]
Current Score: [_score]Observe como o método privado _applyBonus e o campo _bonusMultiplier lidam com o cálculo do bônus internamente. O código externo vê apenas os métodos públicos e não tem ideia sobre o sistema de multiplicadores - isso é um detalhe de implementação oculto atrás da convenção de sublinhado.
Saída 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: 65Folha de consulta
O prefixo de sublinhado _ marca membros como privados no Dart. Essa convenção de nomenclatura controla a visibilidade sem o uso de palavras-chave como private.
Aplique o sublinhado a campos e métodos:
class Counter {
int _count = 0; // Private field
void _increment() { // Private method
_count++;
}
void increase() { // Public method
_increment();
print('Count: $_count');
}
}O sublinhado funciona para qualquer identificador - variáveis, métodos, getters, setters e nomes de classes:
class Person {
String _name; // Private
int _age; // Private
Person(this._name, this._age);
String get name => _name; // Public getter
void _validateAge(int age) { } // Private method
}Membros privados são acessíveis dentro da mesma classe, mas restritos ao código fora da biblioteca. Qualquer coisa que comece com _ é um detalhe de implementação.
Experimente você mesmo
import 'score_tracker.dart';
void main() {
// TODO: Criar um ScoreTracker para o jogador 'Alex'
// TODO: Chamar displayStats()
// TODO: Adicionar 10 pontos
// TODO: Adicionar 25 pontos
// TODO: Ativar o bônus duplo
// TODO: Adicionar 15 pontos (isso deve ser dobrado)
// TODO: Chamar displayStats()
// TODO: Imprimir 'Final score: [score]' usando o getter público
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosBibliotecas e ImportaçõesIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosVariáveis de InstânciaFundamentos de ConstrutoresRecapitulação - Calculadora Simples4Null Safety
Introdução ao Null SafetyNullable vs Non-NullableOs Operadores ? e !Palavra-chave Late e Null SafetyOperadores Null-AwareNull Safety em ClassesRecapitulação - Sistema de Perfil de Usuário7Classes Abstratas e Interfaces
Classes AbstratasMétodos AbstratosInterfaces em DartInterfaces ImplícitasImplementando vs EstendendoMúltiplas InterfacesRecapitulação - Calculadora de Formas10Coleções e Generics
Visão Geral de List, Set e MapColeções Type-SafeClasses GenéricasMétodos GenéricosRestrições de GenericsIterable e IteratorRecapitulação - Armazenamento Genérico13Conceitos Avançados de POO
Composição vs HerançaMétodos de ExtensãoClasses ChamáveisClasses Seladas (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums com Métodos16Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário2Construtores em Dart
Construtor PadrãoConstrutores NomeadosListas de InicializaçãoConstrutores ConstantesConstrutores FactoryConstrutores de RedirecionamentoRecapitulação - Shape Builder5Encapsulamento
Membros Públicos vs PrivadosA Convenção do Prefixo _Privacidade em Nível de BibliotecaAprofundamento em Getters & SettersOcultação de InformaçãoRecapitulação - Registros de Estudantes8Mixins
Introdução aos MixinsCriando MixinsUsando Múltiplos MixinsPalavra-chave on em MixinsMixin vs HerançaMixin vs InterfaceRecapitulação - Sistema Animal11Métodos Especiais
Sobrescrita de toString()Sobrescrita de hashCode & ==Interface ComparableMétodo call()Sobrescrita de noSuchMethodRecapitulação - Coleção Personalizada14Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy3Propriedades de Classe
Membros de Instância vs EstáticosCampos Final & ConstVariáveis LateMétodos e Campos EstáticosGetters e SettersRecapitulação - Gerenciador de Conta Bancária6Herança
Herança BásicaA Palavra-chave superSobrescrita de MétodoA Anotação @overrideA Palavra-chave final para ClassesConstrutores e HerançaRecapitulação - Hierarquia de Funcionários9Polimorfismo
Fundamentos do PolimorfismoPolimorfismo via InterfacesVerificação de Tipos em Tempo de ExecuçãoOs Operadores is & asPalavra-chave CovariantRecapitulação - Processador de Pagamentos12POO Assíncrona
Futures e async/awaitFundamentos de StreamsStream ControllersConstrutores AssíncronosAsync em Métodos de ClasseRecapitulação - Data Fetcher15Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository