Mobile App Development · Dart/Flutter
Reaproveite comportamento entre classes sem herança rígida com mixin e adicione métodos a tipos já existentes com extension.
Nesta aula você vai declarar mixins e aplicá-los em classes com with, entender quando um mixin precisa de on para depender de uma classe base, dar estado a um mixin e criar extensions que adicionam métodos a tipos como String e double sem alterar o código original desses tipos.
mixin
Declara um bloco de comportamento reutilizável que pode ser incorporado em várias classes, sem criar uma hierarquia de herança entre elas.
with
Aplica um ou mais mixins a uma classe. É possível combinar vários mixins na mesma declaração: with A, B.
Um mixin pode declarar atributos, não só métodos. Cada classe que o usa ganha sua própria cópia desse estado.
mixin X on Y
Restringe o mixin a classes que estendem Y. Garante que o mixin possa acessar com segurança membros da classe base.
extension
Adiciona métodos a um tipo existente (como String ou double) sem modificar sua definição original nem usar herança.
extension ... on double
Extensions também funcionam em tipos numéricos — útil para formatação e regras de negócio, como converter um valor para moeda.
Use mixins para comportamento reutilizável e coeso; evite responsabilidades demais em um único mixin. Nomeie extensions de forma clara e não confunda o comportamento original do tipo.
// Demonstração de 'mixin on' — restrição de uso de mixin.
// 'mixin X on Y' significa que X só pode ser aplicado a classes que estendem Y.
// Isso garante que o mixin acesse membros definidos na classe base.
// Classe base com o atributo 'id' que o mixin vai acessar.
class Entidade {
final String id;
Entidade(this.id);
}
// 'on Entidade' restringe: apenas classes que herdam de Entidade podem usar este mixin.
// Dentro do mixin, podemos acessar 'id' porque garantidamente a classe base o tem.
mixin Identificavel on Entidade {
void exibirId() {
// 'id' é acessível porque o mixin só pode ser usado por subclasses de Entidade.
print('ID: $id');
}
}
// Produto herda de Entidade (necessário para aplicar Identificavel) e usa o mixin.
class Produto extends Entidade with Identificavel {
// 'super.id' passa o valor do parâmetro para o construtor da classe pai (Entidade).
Produto(super.id);
}
// Extension sobre double: adiciona formatação de moeda ao tipo nativo.
extension Moeda on double {
String paraReal() => 'R\$ ${toStringAsFixed(2)}';
}
void main() {
Produto produto = Produto('prod-001');
// Chama o método do mixin que acessa o atributo da classe base.
produto.exibirId();
double preco = 49.9;
// 'paraReal()' agora está disponível em qualquer double!
print(preco.paraReal());
}
ID: prod-001 R$ 49.90
with A, B.on que dependa de um atributo de uma classe base.String e outra em double para praticar formatação.