Menu
Coddy logo textTech

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.

challenge icon

Desafio

Fácil

Vamos construir 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 sensíveis de serem acessados diretamente de fora da biblioteca da classe.

Você criará dois arquivos para organizar seu código:

  • credential.dart: Defina uma classe Credential que armazena informações de login para um site. A classe deve ter:
    • Um String website público - não há problema em qualquer pessoa ver para qual site isso se refere
    • Um String username público - o nome de usuário pode ser visível
    • Um String _password privado - a senha real deve ser protegida
    • Um construtor que recebe todos os três valores
    • Um getter público password que retorna o _password privado (acesso controlado)
    • Um método getMaskedPassword() que retorna a senha com todos os caracteres substituídos por asteriscos * (mesmo comprimento da senha real)
    • Um método displayCredential() que imprime as informações da credencial de forma segura (mostrando a senha mascarada, não a real)
  • main.dart: Importe sua classe de credencial e demonstre como o encapsulamento protege a senha:
    • Crie uma credencial para o site 'github.com', nome de usuário 'dev_user' e senha 'secret123'
    • Crie outra credencial para o site 'email.com', nome de usuário 'john_doe' e senha 'myP@ss'
    • Para cada credencial, chame displayCredential(), depois imprima Actual password length: [length] usando o getter público para acessar o comprimento da senha

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: 6

Folha de consulta

O encapsulamento controla o acesso aos dados internos de uma classe, decidindo o que deve ser visível e o que deve permanecer oculto.

No Dart, os membros da classe são públicos por padrão:

class BankAccount {
  String owner;
  double balance;  // Public - can be accessed directly
  
  BankAccount(this.owner, this.balance);
}

var account = BankAccount('Alice', 1000);
account.balance = -500;  // Direct modification allowed

Para proteger os dados internos, use membros privados prefixando o nome com um sublinhado _:

class BankAccount {
  String owner;
  double _balance;  // Private - starts with underscore
  
  BankAccount(this.owner, this._balance);
  
  double get balance => _balance;  // Controlled access via getter
}

Membros privados não podem ser acessados diretamente de fora da biblioteca onde a classe está definida. Use getters e métodos públicos para fornecer acesso controlado aos dados privados, garantindo que os objetos permaneçam em um estado válido.

Experimente 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
}
quiz iconTeste seus conhecimentos

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