Métodos genéricos
Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 66 de 110.
Assim como as classes podem ser genéricas, métodos individuais também podem ter seus próprios parâmetros de tipo. Isso é útil quando você precisa de um método flexível sem tornar a classe inteira genérica.
Um método genérico declara seu parâmetro de tipo antes do tipo de retorno:
T findFirst<T>(List<T> items) {
return items.first;
}
void main() {
var firstNumber = findFirst<int>([1, 2, 3]);
var firstWord = findFirst<String>(['hello', 'world']);
print(firstNumber); // 1
print(firstWord); // olá
}O Dart muitas vezes consegue inferir o tipo a partir dos argumentos, então nem sempre você precisa especificá-lo explicitamente:
var result = findFirst([10, 20, 30]); // Dart infere intMétodos genéricos são particularmente úteis dentro de classes quando apenas determinadas operações precisam de flexibilidade de tipos:
class Printer {
void printItem<T>(T item) {
print('Printing: $item');
}
List<T> duplicate<T>(T item, int count) {
return List.filled(count, item);
}
}
void main() {
var printer = Printer();
printer.printItem<String>('Hello');
printer.printItem(42); // Tipo inferido como int
var copies = printer.duplicate('Hi', 3);
print(copies); // [Hi, Hi, Hi]
}Métodos genéricos oferecem controle refinado sobre a segurança de tipos no nível do método, mantendo suas classes mais simples e ainda permitindo aproveitar a verificação de tipos em tempo de compilação.
Desafio
FácilVamos criar um utilitário de transformação de dados que demonstra o poder dos métodos genéricos. Você vai criar uma classe Transformer com métodos que podem trabalhar com qualquer tipo, oferecendo flexibilidade sem tornar a classe inteira genérica.
Você vai organizar seu código em dois arquivos:
transformer.dart: Crie uma classeTransformercom estes métodos genéricos:T getFirst<T>(List<T> items)- retorna o primeiro elemento de uma listaT getLast<T>(List<T> items)- retorna o último elemento de uma listaList<T> repeat<T>(T item, int times)- cria uma lista que contém o item repetido pelo número de vezes especificadovoid printPair<A, B>(A first, B second)- imprime dois valores no formatoPair: [first] and [second]
main.dart: Importe seu arquivo do transformer e demonstre cada método genérico com tipos diferentes:- Crie uma instância de
Transformer - Use
getFirstem[10, 20, 30]e imprima o resultado - Use
getFirstem['apple', 'banana', 'cherry']e imprima o resultado - Use
getLastem[1.5, 2.5, 3.5]e imprima o resultado - Use
repeatpara criar uma lista de'Hi'repetido4vezes e imprima o resultado - Use
repeatpara criar uma lista de7repetido3vezes e imprima o resultado - Use
printPaircom'Name'e42 - Use
printPaircom100etrue
- Crie uma instância de
Observe como cada método declara seu próprio parâmetro ou seus próprios parâmetros de tipo, permitindo que o mesmo objeto Transformer trabalhe com números inteiros, strings, números de ponto flutuante e valores booleanos — tudo isso com segurança total de tipos. O método printPair demonstra o uso de dois parâmetros de tipo em um único método.
Saída esperada:
10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and trueExperimente você mesmo
import 'transformer.dart';
void main() {
// Crie uma instância de Transformer
var transformer = Transformer();
// TODO: Use getFirst em [10, 20, 30] e imprima o resultado
// TODO: Use getFirst em ['apple', 'banana', 'cherry'] e imprima o resultado
// TODO: Use getLast em [1.5, 2.5, 3.5] e imprima o resultado
// TODO: Use repeat para criar uma lista com 'Hi' repetido 4 vezes e imprima-a
// TODO: Use repeat para criar uma lista com 7 repetido 3 vezes e imprima-a
// TODO: Use printPair com 'Name' e 42
// TODO: Use printPair com 100 e true
}
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 OOP
Arquivos externosBibliotecas e importsIntrodução à OOPClasses vs. objetosA palavra-chave thisMétodosVariáveis de instânciaNoções básicas de construtoresRevisão - Calculadora simples4Segurança contra nulos
Introdução à segurança contra nulosAnulável vs. não anulávelOs operadores ? e !Palavra-chave Late e segurança contra nulosOperadores conscientes de nulosSegurança contra nulos em classesRecapitulação — Sistema de perfil de usuário7Classes Abstratas e Interfaces
Classes AbstratasMétodos AbstratosInterfaces em DartInterfaces ImplícitasImplementação vs. ExtensãoMúltiplas InterfacesRecapitulação - Calculadora de Formas10Coleções e Genéricos
Visão geral de List, Set e MapColeções com segurança de tiposClasses genéricasMétodos genéricosRestrições genéricasIterable e IteratorRecapitulação - Armazenamento genérico13Conceitos Avançados de OOP
Composição vs. HerançaMétodos de ExtensãoClasses ChamáveisClasses Seladas (Dart 3)Registros (Dart 3)Padrões e Correspondência (3.0)Enums com Métodos16Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários2Construtores em Dart
Construtor padrãoConstrutores nomeadosListas de inicializaçãoConstrutores constantesConstrutores factoryConstrutores de redirecionamentoRevisão - Construtor de formas5Encapsulamento
Membros Públicos vs. PrivadosConvenção do Prefixo _Privacidade no Nível da BibliotecaAprofundamento em Getters e SettersOcultação de InformaçõesRecapitulação - Registros de Alunos8Mixins
Introdução a MixinsCriando MixinsUsando vários MixinsPalavra-chave on em MixinsMixin vs HerançaMixin vs InterfaceRecapitulação - Sistema de Animais11Métodos Especiais
Sobrescrita de toString()Sobrescrita de hashCode e ==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 e ConstVariáveis LateMétodos e Campos EstáticosGetters e SettersRecapitulação - Gerenciador de Contas Bancárias6Herança
Herança BásicaA Palavra-chave superSobrescrita de MétodosA Anotação @overrideA Palavra-chave final para ClassesConstrutores e HerançaRecapitulação - Hierarquia de Funcionários9Polimorfismo
Fundamentos do polimorfismoPolimorfismo por meio de interfacesVerificação de tipos em tempo de execuçãoOs operadores is e asPalavra-chave covarianteRecapitulação — Processador de pagamentos12OOP Assíncrona
Futures e async/awaitNoções básicas de StreamsControladores de StreamConstrutores assíncronosAsync em métodos de classeRecapitulação — Buscador de dados15Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão RepositoryPratique por conta própria: Compilador de Dart online