Genericos
## Objetivos de Aprendizaje
- Comprender tipos genericos
- Crear clases y funciones genericas
- Dominar parametros de tipo limitados
- Aprender restricciones de tipo
## Por Que Genericos?
### Sin Genericos
```dart
class Stack {
List _items = [];
void push(dynamic item) => _items.add(item);
dynamic pop() => _items.removeLast();
}
void main() {
var stack = Stack();
stack.push(1);
stack.push('string'); // Permitido pero no seguro
var item = stack.pop();
// print(item.length); // Error en tiempo de ejecucion si item es int!
}
```
### Con Genericos
```dart
class Stack {
List _items = [];
void push(T item) => _items.add(item);
T pop() => _items.removeLast();
}
void main() {
var intStack = Stack();
intStack.push(1);
// intStack.push('string'); // Error!
var stringStack = Stack();
stringStack.push('hello');
print(stringStack.pop().length); // 5
}
```
## Clases Genericas
### Ejemplo Box
```dart
class Box {
T _value;
Box(this._value);
T get value => _value;
void set value(T value) => _value = value;
}
void main() {
var intBox = Box(42);
print(intBox.value); // 42
var stringBox = Box('Hola');
print(stringBox.value); // Hola
var dynamicBox = Box(42); // Funciona pero pierde seguridad de tipos
// dynamicBox.value es aun int, pero el compilador no lo sabe
}
```
### Multiples Parametros de Tipo
```dart
class Pair {
K first;
V second;
Pair(this.first, this.second);
@override
String toString() => '($first, $second)';
}
void main() {
var pair = Pair('edad', 30);
print(pair); // (edad, 30)
var entry = Pair.of(1, 'uno');
print(entry); // (1, uno)
}
```
## Funciones Genericas
### Funcion Generica Basica
```dart
T first(List list) {
if (list.isEmpty) {
throw Exception('Lista vacia');
}
return list.first;
}
void main() {
print(first([1, 2, 3])); // 1
print(first(['a', 'b', 'c'])); // a
}
```
### Metodo Generico
```dart
class Utils {
static T maximum>(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
}
void main() {
print(Utils.maximum(5, 10)); // 10
print(Utils.maximum('manzana', 'platano')); // platano
}
```
## Parametros de Tipo Limitados
### Restriccion extends
```dart
// T debe extender num (int, double, etc.)
class NumericBox {
T _value;
NumericBox(this._value);
T square() => _value * _value as T;
}
void main() {
var intBox = NumericBox(5);
print(intBox.square()); // 25
var doubleBox = NumericBox(3.5);
print(doubleBox.square()); // 12.25
// NumericBox(); // Error: String no extiende num
}
```
### Multiples Limites
```dart
class ComparablePair, V extends Comparable> {
K key;
V value;
ComparablePair(this.key, this.value);
bool isKeyGreater() => key.compareTo(key) > 0;
}
```
## Colecciones Genericas
### List
```dart
void main() {
List numbers = [1, 2, 3, 4, 5];
List names = ['Alice', 'Bob', 'Charlie'];
// List puede contener cualquier cosa
List mixed = [1, 'dos', 3.0];
}
```
### Map
```dart
void main() {
Map ages = {
'Alice': 30,
'Bob': 25,
};
Map ids = {
1: 'uno',
2: 'dos',
};
}
```
### Set
```dart
void main() {
Set numbers = {1, 2, 3, 4, 5};
Set uniqueNames = {'Alice', 'Bob', 'Alice'}; // {'Alice', 'Bob'}
}
```
## Interfaces Genericos
### Interfaz Generico
```dart
abstract class Repository {
Future getById(String id);
Future
- > getAll();
Future
- > getAll() async => [];
@override
Future
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →