Menu
Coddy logo textTech

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.

challenge icon

Desafio

Fácil

Vamos 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 Formattable que contém:
      • Uma propriedade String prefix inicializada como '>>>'
      • Um getter separator que retorna ' | '
      • Um método format(String text) que retorna a string [prefix][separator][text]
      • Um método formatBold(String text) que retorna **[text]**
    • Uma classe TextMessage que usa o mixin Formattable. Adicione uma propriedade String sender com um construtor. Inclua um método send(String content) que imprime o resultado da chamada de format() com [sender]: [content]
    • Uma classe AlertMessage que também usa o mixin Formattable. Adicione uma propriedade String level com um construtor. Inclua um método alert(String content) que imprime o resultado da chamada de format() com [[level]] [formatBold(content)]
  • 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 TextMessage com o sender 'Alice'
    • Crie um AlertMessage com o level 'WARNING'
    • Chame send('Hello there!') na mensagem de texto
    • Chame alert('System overload') na mensagem de alerta

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
}
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