Membros Públicos vs. Privados
Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 30 de 110.
Encapsulamento é um dos princípios fundamentais da programação orientada a objetos. Trata-se de controlar o acesso aos dados internos de uma classe, decidindo o que deve ser visível para o mundo exterior e o que deve permanecer oculto.
No Dart, os membros de classe (campos e métodos) são públicos por padrão. Isso significa que qualquer código pode acessá-los diretamente:
class BankAccount {
String owner;
double balance;
BankAccount(this.owner, this.balance);
}
var account = BankAccount('Alice', 1000);
account.balance = -500; // Qualquer pessoa pode modificar isso diretamente!Isso é problemático. Nada impede a definição de um saldo inválido.
Para proteger dados internos, o Dart usa membros privados. Um membro torna-se privado quando seu nome começa com um sublinhado _:
class BankAccount {
String owner;
double _balance; // Privado - começa com sublinhado
BankAccount(this.owner, this._balance);
double get balance => _balance; // Acesso controlado
}Agora _balance não pode ser acessado diretamente de fora da biblioteca onde a classe está definida. O código externo deve usar o getter público em seu lugar. Isso permite que você controle como os dados são lidos e modificados, garantindo que seus objetos permaneçam sempre em um estado válido.
Desafio
FácilVamos criar um gerenciador de senhas simples que demonstra a diferença entre membros públicos e privados. Você verá como o prefixo de sublinhado protege dados confidenciais contra o acesso direto de fora da biblioteca da classe.
Você criará dois arquivos para organizar seu código:
credential.dart: Defina uma classeCredentialque armazena informações de login de um site. A classe deve ter:- Uma
String websitepública — não há problema em qualquer pessoa ver para qual site ela é - Uma
String usernamepública — o nome de usuário pode ser visível - Uma
String _passwordprivada — a senha real deve ser protegida - Um construtor que recebe os três valores
- Um getter público
passwordque retorna a_passwordprivada (acesso controlado) - Um método
getMaskedPassword()que retorna a senha com todos os caracteres substituídos por asteriscos*(com o mesmo comprimento da senha real) - Um método
displayCredential()que imprime as informações da credencial com segurança (mostrando a senha mascarada, não a real)
- Uma
main.dart: Importe sua classe de credencial e demonstre como o encapsulamento protege a senha:- Crie uma credencial para o site
'github.com', com o nome de usuário'dev_user'e a senha'secret123' - Crie outra credencial para o site
'email.com', com o nome de usuário'john_doe'e a senha'myP@ss' - Para cada credencial, chame
displayCredential()e, em seguida, imprimaActual password length: [length]usando o getter público para acessar o comprimento da senha
- Crie uma credencial para o site
O método displayCredential() deve imprimir neste formato:
--- Credential ---
Website: [website]
Username: [username]
Password: [maskedPassword]Saída esperada:
--- Credential ---
Website: github.com
Username: dev_user
Password: *********
Actual password length: 9
--- Credential ---
Website: email.com
Username: john_doe
Password: ******
Actual password length: 6Experimente você mesmo
import 'credential.dart';
void main() {
// TODO: Criar uma credencial para github.com
// website: 'github.com', username: 'dev_user', password: 'secret123'
// TODO: Chamar displayCredential() na primeira credencial
// TODO: Imprimir o comprimento real da senha usando o getter público
// Formato: "Actual password length: [length]"
// TODO: Criar uma credencial para email.com
// website: 'email.com', username: 'john_doe', password: 'myP@ss'
// TODO: Chamar displayCredential() na segunda credencial
// TODO: Imprimir o comprimento real da senha 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 OOP
Arquivos externosBibliotecas e importsIntrodução à OOPClasses vs. objetosA palavra-chave thisMétodosVariáveis de instânciaNoções básicas de construtoresRevisão - Calculadora simples4Segurança contra nulos
Introdução à segurança contra nulosAnulável vs. não anulávelOs operadores ? e !Palavra-chave Late e segurança contra nulosOperadores conscientes de nulosSegurança contra nulos em classesRecapitulação — Sistema de perfil de usuário7Classes Abstratas e Interfaces
Classes AbstratasMétodos AbstratosInterfaces em DartInterfaces ImplícitasImplementação vs. ExtensãoMúltiplas InterfacesRecapitulação - Calculadora de Formas10Coleções e Genéricos
Visão geral de List, Set e MapColeções com segurança de tiposClasses genéricasMétodos genéricosRestrições genéricasIterable e IteratorRecapitulação - Armazenamento genérico13Conceitos Avançados de OOP
Composição vs. HerançaMétodos de ExtensãoClasses ChamáveisClasses Seladas (Dart 3)Registros (Dart 3)Padrões e Correspondência (3.0)Enums com Métodos16Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários2Construtores em Dart
Construtor padrãoConstrutores nomeadosListas de inicializaçãoConstrutores constantesConstrutores factoryConstrutores de redirecionamentoRevisão - Construtor de formas5Encapsulamento
Membros Públicos vs. PrivadosConvenção do Prefixo _Privacidade no Nível da BibliotecaAprofundamento em Getters e SettersOcultação de InformaçõesRecapitulação - Registros de Alunos8Mixins
Introdução a MixinsCriando MixinsUsando vários MixinsPalavra-chave on em MixinsMixin vs HerançaMixin vs InterfaceRecapitulação - Sistema de Animais11Métodos Especiais
Sobrescrita de toString()Sobrescrita de hashCode e ==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 e ConstVariáveis LateMétodos e Campos EstáticosGetters e SettersRecapitulação - Gerenciador de Contas Bancárias6Herança
Herança BásicaA Palavra-chave superSobrescrita de MétodosA Anotação @overrideA Palavra-chave final para ClassesConstrutores e HerançaRecapitulação - Hierarquia de Funcionários9Polimorfismo
Fundamentos do polimorfismoPolimorfismo por meio de interfacesVerificação de tipos em tempo de execuçãoOs operadores is e asPalavra-chave covarianteRecapitulação — Processador de pagamentos12OOP Assíncrona
Futures e async/awaitNoções básicas de StreamsControladores de StreamConstrutores assíncronosAsync em métodos de classeRecapitulação — Buscador de dados15Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão RepositoryPratique por conta própria: Compilador de Dart online