Menu
Coddy logo textTech

Mixin vs Interface

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 55 de 110.

Você viu como os mixins se comparam à herança. Agora vamos comparar mixins com interfaces, já que ambos permitem que você trabalhe com múltiplos tipos. A principal diferença é o que eles fornecem: interfaces definem um contrato, enquanto mixins fornecem implementação.

Quando você implementa uma interface, promete fornecer determinados métodos, mas escreve todo o código por conta própria. Quando usa um mixin, obtém o código real gratuitamente.

// Abordagem de interface - você deve implementar tudo
abstract class Printable {
  void printInfo();
}

class Report implements Printable {
  @override
  void printInfo() {
    print('Printing report...');  // Você escreve isso
  }
}

// Abordagem de mixin - implementação incluída
mixin Printable {
  void printInfo() {
    print('Printing...');  // Já escrito para você
  }
}

class Report with Printable {}  // Recebe printInfo() automaticamente

Então, quando você deve usar cada um? Use uma interface quando classes diferentes precisarem das mesmas assinaturas de método, mas de implementações diferentes. Use um mixin quando as classes deverem compartilhar exatamente o mesmo comportamento.

RecursoInterfaceMixin
ForneceApenas o contratoContrato + código
ImplementaçãoVocê escreveIncluída
Palavra-chaveimplementswith
Ideal paraComportamentos diferentes, mesma APIComportamento compartilhado

Você pode até combinar ambas as abordagens - use interfaces para definir o que uma classe pode fazer e mixins para fornecer implementações comuns onde for apropriado. No Dart, ao combinar ambos, sempre coloque with antes de implements:

class MyClass with SomeMixin implements SomeInterface {
  // with vem antes de implements
}
challenge icon

Desafio

Fácil

Vamos criar um sistema de notificações que demonstra quando usar interfaces em vez de mixins. Você criará uma interface para notificações que exigem implementações diferentes e um mixin para o comportamento de registro compartilhado que deve ser idêntico em todos os tipos de notificação.

Você organizará seu código em três arquivos:

  • notifiable.dart: defina uma classe abstrata Notifiable que atua como uma interface. Ela deve declarar dois métodos abstratos: send(String message) e getChannel(), que retorna uma String. Diferentes tipos de notificação implementarão esses métodos de maneiras diferentes, com base em seu canal específico.
  • logging.dart: crie um mixin Logging que forneça o comportamento compartilhado que todas as notificações devem ter. Inclua um método logSent(String channel, String message) que imprima [LOG] Sent via [channel]: [message] e um método logTimestamp() que imprima [LOG] Timestamp recorded. Esse comportamento é idêntico para todos os tipos de notificação, o que o torna perfeito para um mixin.
  • main.dart: importe os dois arquivos e crie duas classes de notificação que combinem a interface com o mixin:
    • Uma classe EmailNotification que use o mixin Logging e implemente Notifiable. Seu getChannel() deve retornar 'Email', e seu método send() deve imprimir Sending email: [message], depois chamar logSent() com o canal e a mensagem e, em seguida, chamar logTimestamp()
    • Uma classe SMSNotification que use o mixin Logging e implemente Notifiable. Seu getChannel() deve retornar 'SMS', e seu método send() deve imprimir Sending SMS: [message], depois chamar logSent() com o canal e a mensagem e, em seguida, chamar logTimestamp()
    Em seguida, crie um EmailNotification e chame send('Hello World'), imprima uma linha vazia, crie um SMSNotification e chame send('Quick update')

Observe como a interface força cada classe a escrever suas próprias implementações de send() e getChannel() (comportamento diferente), enquanto o mixin fornece os métodos de registro que funcionam de forma idêntica para ambas (comportamento compartilhado).

Saída esperada:

Sending email: Hello World
[LOG] Sent via Email: Hello World
[LOG] Timestamp recorded

Sending SMS: Quick update
[LOG] Sent via SMS: Quick update
[LOG] Timestamp recorded

Experimente você mesmo

import 'notifiable.dart';
import 'logging.dart';

// TODO: Criar a classe EmailNotification que:
//       - usa o mixin Logging (with)
//       - implementa Notifiable (implements)
//       - getChannel() retorna 'Email'
//       - send() imprime 'Sending email: [message]', depois chama logSent(), depois logTimestamp()

// TODO: Criar a classe SMSNotification que:
//       - usa o mixin Logging (with)
//       - implementa Notifiable (implements)
//       - getChannel() retorna 'SMS'
//       - send() imprime 'Sending SMS: [message]', depois chama logSent(), depois logTimestamp()

void main() {
  // TODO: Criar uma EmailNotification e chamar send('Hello World')
  
  // TODO: Imprimir uma linha vazia
  
  // TODO: Criar uma SMSNotification e chamar send('Quick update')
}
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

Pratique por conta própria: Compilador de Dart online