Métodos genéricos
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 66 de 110.
Al igual que las clases pueden ser genéricas, los métodos individuales también pueden tener sus propios parámetros de tipo. Esto resulta útil cuando necesitas un método flexible sin hacer que toda la clase sea genérica.
Un método genérico declara su parámetro de tipo antes del 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); // hello
}Dart a menudo puede inferir el tipo a partir de los argumentos, así que no siempre necesitas especificarlo explícitamente:
var result = findFirst([10, 20, 30]); // Dart infiere intLos métodos genéricos son especialmente útiles dentro de las clases cuando solo ciertas operaciones necesitan flexibilidad 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]
}Los métodos genéricos te dan un control preciso de la seguridad de tipos a nivel de método, lo que permite mantener tus clases más sencillas y, al mismo tiempo, beneficiarte de la comprobación de tipos en tiempo de compilación.
Desafío
FácilVamos a crear una utilidad de transformación de datos que muestre el poder de los métodos genéricos. Crearás una clase Transformer con métodos que puedan trabajar con cualquier tipo, lo que te dará flexibilidad sin hacer genérica toda la clase.
Organizarás el código en dos archivos:
transformer.dart: Crea una claseTransformercon estos métodos genéricos:T getFirst<T>(List<T> items): devuelve el primer elemento de una listaT getLast<T>(List<T> items): devuelve el último elemento de una listaList<T> repeat<T>(T item, int times): crea una lista que contiene el elemento repetido la cantidad de veces especificadavoid printPair<A, B>(A first, B second): imprime dos valores con el formatoPair: [first] and [second]
main.dart: Importa el archivo del transformador y muestra cada método genérico con distintos tipos:- Crea una instancia de
Transformer - Usa
getFirstcon[10, 20, 30]e imprime el resultado - Usa
getFirstcon['apple', 'banana', 'cherry']e imprime el resultado - Usa
getLastcon[1.5, 2.5, 3.5]e imprime el resultado - Usa
repeatpara crear una lista con'Hi'repetido4veces e imprime el resultado - Usa
repeatpara crear una lista con7repetido3veces e imprime el resultado - Usa
printPaircon'Name'y42 - Usa
printPaircon100ytrue
- Crea una instancia de
Observa cómo cada método declara sus propios parámetros de tipo, lo que permite que el mismo objeto Transformer trabaje con enteros, cadenas, números de coma flotante y valores booleanos, todo con seguridad de tipos completa. El método printPair muestra cómo usar dos parámetros de tipo en un solo método.
Salida esperada:
10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and truePruébalo tú mismo
import 'transformer.dart';
void main() {
// Crea una instancia de Transformer
var transformer = Transformer();
// TODO: Usa getFirst con [10, 20, 30] e imprime el resultado
// TODO: Usa getFirst con ['apple', 'banana', 'cherry'] e imprime el resultado
// TODO: Usa getLast con [1.5, 2.5, 3.5] e imprime el resultado
// TODO: Usa repeat para crear una lista con 'Hi' repetido 4 veces e imprímela
// TODO: Usa repeat para crear una lista con 7 repetido 3 veces e imprímela
// TODO: Usa printPair con 'Name' y 42
// TODO: Usa printPair con 100 y true
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online