Criando Mixins
Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 51 de 110.
Agora que você entende o que são mixins, vamos ver como criá-los corretamente. Um mixin é declarado usando a palavra-chave mixin em vez de class.
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Mixins podem conter métodos, propriedades e até mesmo getters e setters - assim como as classes. No entanto, há uma regra importante: mixins não podem ter construtores. Como os mixins devem ser "misturados" (mixed in) em vez de instanciados diretamente, eles não precisam de lógica de inicialização.
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // Usa o método do mixin
print(doc.createdAt); // Usa a propriedade do mixin
}Quando você aplica um mixin com with, todos os seus membros tornam-se parte da sua classe. A classe pode usá-los diretamente, assim como qualquer código que possua uma instância dessa classe. Isso torna os mixins uma maneira limpa de adicionar funcionalidade reutilizável sem a complexidade das hierarquias de herança.
Desafio
FácilVamos construir um sistema de mensagens que demonstra como criar mixins com métodos, propriedades e getters. Você projetará um mixin que adiciona recursos de formatação a diferentes tipos de mensagens.
Você organizará seu código em dois arquivos:
messaging.dart: Defina seu mixin e as classes de mensagem aqui:- Um mixin
Formattableque contém:- Uma propriedade
String prefixinicializada como'>>>' - Um getter
separatorque retorna' | ' - Um método
format(String text)que retorna a string[prefix][separator][text] - Um método
formatBold(String text)que retorna**[text]**
- Uma propriedade
- Uma classe
TextMessageque usa o mixinFormattable. Adicione uma propriedadeString sendercom um construtor. Inclua um métodosend(String content)que imprime o resultado da chamada deformat()com[sender]: [content] - Uma classe
AlertMessageque também usa o mixinFormattable. Adicione uma propriedadeString levelcom um construtor. Inclua um métodoalert(String content)que imprime o resultado da chamada deformat()com[[level]] [formatBold(content)]
- Um mixin
main.dart: Importe seu arquivo de mensagens e demonstre como ambos os tipos de mensagens ganham recursos de formatação a partir do mixin:- Crie um
TextMessagecom o sender'Alice' - Crie um
AlertMessagecom o level'WARNING' - Chame
send('Hello there!')na mensagem de texto - Chame
alert('System overload')na mensagem de alerta
- Crie um
Seu mixin demonstra que mixins podem conter propriedades com valores padrão, getters que computam valores e múltiplos métodos que podem até chamar uns aos outros. Ambas as classes de mensagem ganham toda essa funcionalidade simplesmente usando a palavra-chave with.
Saída esperada:
>>> | Alice: Hello there!
>>> | [WARNING] **System overload**Folha de consulta
Mixins são declarados usando a palavra-chave mixin em vez de class:
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Mixins podem conter métodos, propriedades, getters e setters, mas não podem ter construtores:
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}Aplique mixins a classes usando a palavra-chave with. Todos os membros do mixin tornam-se parte da classe:
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // Usa o método do mixin
print(doc.createdAt); // Usa a propriedade do mixin
}Experimente você mesmo
import 'messaging.dart';
void main() {
// TODO: Crie um TextMessage com o remetente 'Alice'
// TODO: Crie um AlertMessage com o nível 'WARNING'
// TODO: Chame send('Hello there!') na mensagem de texto
// TODO: Chame alert('System overload') na mensagem de alerta
}
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