Menu
Coddy logo textTech

Privacidade em Nível de Biblioteca

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 32 de 110.

No Dart, a privacidade é aplicada no nível da biblioteca, não no nível da classe. Esta é uma distinção fundamental em relação a linguagens como Java ou C++. Uma biblioteca no Dart é tipicamente um único arquivo, ou múltiplos arquivos conectados com diretivas part.

Membros privados (aqueles que começam com _) são acessíveis em qualquer lugar dentro da mesma biblioteca, mesmo a partir de outras classes:

// Ambas as classes no mesmo arquivo (mesma biblioteca)
class Engine {
  int _horsepower = 200;  // Privado para esta biblioteca
}

class Car {
  void showPower(Engine engine) {
    print(engine._horsepower);  // Acessível! Mesma biblioteca
  }
}

No entanto, quando você importa uma classe de um arquivo diferente, seus membros privados tornam-se verdadeiramente ocultos:

// file: engine.dart
class Engine {
  int _horsepower = 200;
  int get power => _horsepower;
}

// file: main.dart
import 'engine.dart';

void main() {
  var engine = Engine();
  // print(engine._horsepower);  // Error! Not accessible
  print(engine.power);           // Works - using public getter
}

Essa privacidade em nível de biblioteca significa que classes no mesmo arquivo podem colaborar estreitamente, enquanto ainda ocultam detalhes de implementação do código externo. É uma escolha de design deliberada que incentiva a organização de classes relacionadas juntas na mesma biblioteca.

challenge icon

Desafio

Fácil

Vamos construir um sistema de colaboração de equipe que demonstra como a privacidade em nível de biblioteca funciona no Dart. Você verá como classes no mesmo arquivo podem acessar os membros privados umas das outras, enquanto o código em arquivos separados não pode.

Você organizará seu código em dois arquivos:

  • team.dart: Este arquivo conterá duas classes que trabalham em conjunto na mesma biblioteca:
    • Uma classe Member com uma String name pública e um int _performanceScore privado inicializado em 50. Inclua um construtor que receba o nome e um getter público performanceScore que retorne a pontuação privada.
    • Uma classe TeamLead no mesmo arquivo que pode acessar o campo privado de Member diretamente (porque estão na mesma biblioteca). Esta classe deve ter uma String name pública, um construtor que receba o nome e um método evaluateMember(Member member) que acesse diretamente member._performanceScore, adicione 10 a ele e imprima [leadName] boosted [memberName]'s score to [newScore].
  • main.dart: Importe seu arquivo de equipe e demonstre a diferença no acesso:
    • Crie um Member chamado 'Alice'
    • Crie um TeamLead chamado 'Bob'
    • Imprima Initial score: [score] usando o getter público em Alice
    • Faça Bob avaliar Alice usando evaluateMember
    • Imprima Updated score: [score] usando o getter público
    • Imprima Direct access from main: Not allowed (isso nos lembra que o main.dart não pode acessar _performanceScore diretamente, pois está em uma biblioteca diferente)

A principal lição aqui é que o TeamLead pode ler e modificar diretamente o _performanceScore privado do Member porque ambas as classes residem no mesmo arquivo (mesma biblioteca). No entanto, o código em main.dart deve usar o getter público porque está em uma biblioteca diferente.

Saída esperada:

Initial score: 50
Bob boosted Alice's score to 60
Updated score: 60
Direct access from main: Not allowed

Folha de consulta

No Dart, a privacidade é aplicada no nível da biblioteca, não no nível da classe. Uma biblioteca é tipicamente um único arquivo, ou múltiplos arquivos conectados com diretivas part.

Membros privados começam com um sublinhado (_) e são acessíveis em qualquer lugar dentro da mesma biblioteca, mesmo a partir de outras classes:

// Ambas as classes no mesmo arquivo (mesma biblioteca)
class Engine {
  int _horsepower = 200;  // Privado para esta biblioteca
}

class Car {
  void showPower(Engine engine) {
    print(engine._horsepower);  // Acessível! Mesma biblioteca
  }
}

Quando você importa uma classe de um arquivo diferente, seus membros privados tornam-se ocultos:

// arquivo: engine.dart
class Engine {
  int _horsepower = 200;
  int get power => _horsepower;
}

// arquivo: main.dart
import 'engine.dart';

void main() {
  var engine = Engine();
  // print(engine._horsepower);  // Erro! Não acessível
  print(engine.power);           // Funciona - usando getter público
}

Este design incentiva a organização de classes relacionadas juntas na mesma biblioteca, permitindo que elas colaborem de perto enquanto ocultam detalhes de implementação do código externo.

Experimente você mesmo

import 'team.dart';

void main() {
  // TODO: Criar um Member chamado 'Alice'

  // TODO: Criar um TeamLead chamado 'Bob'

  // TODO: Imprimir "Initial score: [score]" usando o getter público em Alice

  // TODO: Fazer Bob avaliar Alice usando evaluateMember

  // TODO: Imprimir "Updated score: [score]" usando o getter público

  // TODO: Imprimir "Direct access from main: Not allowed"
  // Nota: Não podemos acessar alice._performanceScore aqui porque
  // main.dart está em uma biblioteca diferente de team.dart
}
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