🎯Modificadores de Classes no Dart
O que são Modificadores de Classe em Dart 3
Os modificadores de classe em Dart 3 controlam como uma classe ou mixin pode ser usada dentro de sua própria biblioteca ou fora dela. Uma biblioteca em Dart é uma coleção de código que pode ser importada em outros códigos.
Ou seja... os modificadores funcionam como regras de acesso que determinam o que outros desenvolvedores podem fazer com suas classes quando eles importam sua biblioteca. Isso ajuda a proteger seu código e garantir que ele seja usado da maneira que você pretende.
Os modificadores aparecem antes da declaração de uma classe ou mixin. O conjunto completo de modificadores inclui: abstract, base, final, interface, sealed e mixin.
Classes Normais (Sem Modificador)
Uma classe sem modificador permite permissões irrestritas
Pode ser instanciada/construída de qualquer biblioteca
Pode ser estendida/herdada de qualquer biblioteca
Pode ser implementada de qualquer biblioteca
Pode ser usada com mixin ou como uma classe mixin
Ou seja... uma classe normal sem modificadores não tem restrições - qualquer pessoa que importe sua biblioteca pode fazer qualquer coisa com ela: criar instâncias, estender para criar novas classes, ou implementar sua interface.
Exemplo:
// arquivo: vehicle.dart
class Vehicle {
void move() {
print("O veículo está se movendo");
}
}
// arquivo: main.dart (fora da biblioteca)
import 'vehicle.dart';
// Instanciação - PERMITIDO
var meuVeiculo = Vehicle();
// Herança - PERMITIDO
class Car extends Vehicle {
@override
void move() {
print("O carro está dirigindo");
}
}
// Implementação - PERMITIDO
class Drone implements Vehicle {
@override
void move() {
print("O drone está voando");
}
}Diferença entre extend e implement:
Extend (estender): Usado para herança, onde uma subclasse herda propriedades e métodos da superclasse. Subclasses podem sobrescrever métodos para fornecer implementações personalizadas.
Implement (implementar): Usado para adotar uma interface, onde uma classe concorda em implementar métodos específicos. A classe deve fornecer todos os métodos especificados pela interface.
Ou seja... com extends, você herda implementações existentes e pode escolher sobrescrevê-las. Com implements, você apenas concorda com um contrato e deve implementar tudo do zero.
Classes Abstract
Propósito: Definir comportamentos que podem ser herdados por outras classes
Características: Não requerem implementação concreta completa de sua interface
Métodos: Frequentemente têm métodos abstratos (sem corpo/implementação)
Restrições:
Não podem ser instanciadas/construídas de nenhuma biblioteca
Podem ser estendidas/herdadas de qualquer biblioteca
Podem ser implementadas de qualquer biblioteca
Ou seja... classes abstratas são como "plantas baixas" ou "contratos parcialmente preenchidos" - elas definem uma estrutura, podem ter alguns métodos já implementados, mas também podem ter métodos abstratos que as subclasses precisam implementar. Você não pode criar objetos diretamente de classes abstratas.
Exemplo:
Classes Base
Propósito: Forçar a herança da implementação de uma classe ou mixin
Restrições:
Podem ser instanciadas/construídas de qualquer biblioteca
Podem ser estendidas/herdadas de qualquer biblioteca
Não podem ser implementadas fora de sua própria biblioteca
Regra importante: Qualquer classe que implementa ou estende uma classe base deve ser marcada como
base,finalousealed
Ou seja... classes base garantem que sua implementação seja respeitada quando alguém estender sua classe. Outras pessoas podem criar instâncias e estender suas classes base, mas não podem apenas implementar sua interface ignorando sua implementação. Isso protege a integridade do seu design.
Exemplo:
Classes Interface
Propósito: Fornecer uma interface a ser implementada
Restrições:
Podem ser instanciadas/construídas de qualquer biblioteca
Não podem ser estendidas/herdadas fora de sua própria biblioteca
Podem ser implementadas de qualquer biblioteca
Interface pura: Combinando modificadores
interfaceeabstract, cria-se uma interface pura
Ou seja... classes interface permitem que outros implementem seu "contrato" (métodos), mas não podem estender diretamente seu código. Isso é útil quando você quer que outros sigam sua API, mas não quer que herdem sua implementação específica.
Exemplo:
Classes Final
Propósito: Evitar tanto herança quanto implementação fora da biblioteca
Restrições:
Podem ser instanciadas/construídas de qualquer biblioteca
Não podem ser estendidas/herdadas fora de sua própria biblioteca
Não podem ser implementadas fora de sua própria biblioteca
Ou seja... classes finais são completamente "fechadas" - outros desenvolvedores só podem usar instâncias delas exatamente como você as criou. Elas não podem ser modificadas, estendidas ou reimplementadas. Isso é útil para classes que precisam manter total controle sobre seu comportamento.
Exemplo:
Classes Sealed
Propósito: Representar um conjunto finito de possíveis estados ou tipos
Utilidade: Verificação de exaustividade em declarações switch
Restrições:
Não podem ser instanciadas/construídas de nenhuma biblioteca
Não podem ser estendidas/herdadas fora de sua própria biblioteca
Não podem ser implementadas fora de sua própria biblioteca
Suas subclasses podem ser instanciadas de qualquer biblioteca
Ou seja... classes sealed são perfeitas para criar hierarquias fechadas como estados de uma máquina de estados ou tipos de mensagens em um sistema. O compilador pode verificar se você tratou todos os casos possíveis em um switch, o que evita bugs quando novos tipos são adicionados.
Exemplo:
Mixins
Propósito: Reutilizar código de classe em várias hierarquias de classe sem usar herança tradicional
Uso: Usado com a palavra-chave
withseguida por um ou mais nomes de mixinVantagem: Permite herdar comportamentos sem criar uma hierarquia profunda de herança
Ou seja... mixins são como "pacotes de funcionalidade" que você pode adicionar a qualquer classe. Diferente da herança, que limita você a uma única superclasse, você pode aplicar vários mixins a uma classe, o que torna seu código mais modular e reutilizável.
Exemplo:
Resumo das Permissões Fora da Biblioteca
Sem modificador
✅
✅
✅
abstract
❌
✅
✅
base
✅
✅
❌
interface
✅
❌
✅
final
✅
❌
❌
sealed
❌
❌
❌
Ou seja... esta tabela é um guia rápido para entender o que cada modificador permite ou proíbe quando sua classe é usada por outros desenvolvedores que importam sua biblioteca.
Last updated