Interfaz Comparable
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 72 de 110.
Mientras que == te indica si dos objetos son iguales, a veces necesitas saber cuál va primero. La interfaz Comparable permite que tus objetos se ordenen definiendo un orden natural.
Para hacer que una clase sea comparable, implemente Comparable<T> y sobrescriba el método compareTo. Este método devuelve un número negativo si this va antes que other, cero si son iguales, y un número positivo si this va después:
class Student implements Comparable<Student> {
String name;
int grade;
Student(this.name, this.grade);
@override
int compareTo(Student other) {
return grade.compareTo(other.grade);
}
}
void main() {
var students = [
Student('Alice', 85),
Student('Bob', 92),
Student('Carol', 78),
];
students.sort();
for (var s in students) {
print('${s.name}: ${s.grade}');
}
// Carol: 78, Alice: 85, Bob: 92
}Una vez que tu clase implemente Comparable, puedes usar sort() sin proporcionar un comparador personalizado. Los tipos numéricos y de cadena integrados ya implementan Comparable, razón por la cual grade.compareTo(other.grade) funciona directamente.
Para el orden descendente, simplemente invierta la comparación intercambiando los objetos o negando el resultado:
@override
int compareTo(Student other) {
return other.grade.compareTo(grade); // Descendente
}Desafío
Fácil¡Vamos a construir un sistema de gestión de tareas donde las tareas se puedan ordenar por su nivel de prioridad! Crearás una clase Task que implemente la interfaz Comparable, permitiendo que una lista de tareas se ordene automáticamente de mayor a menor prioridad.
Organizarás tu código en dos archivos:
task.dart: Crea una claseTaskque represente un elemento por hacer con unname(String) ypriority(int, donde los números más altos significan mayor prioridad). Tu tarea debe implementarComparable<Task>para que, al ser ordenada, las tareas aparezcan en orden descendente por prioridad (la prioridad más alta primero). También sobrescribetoString()para devolver el formato:[name] (Priority: [priority])main.dart: Importa tu archivo de tareas y demuestra cómo la interfazComparablepermite el ordenamiento automático. Crea una lista que contenga estas cuatro tareas:'Write report'con prioridad2'Fix critical bug'con prioridad5'Update documentation'con prioridad1'Review code'con prioridad3
Before sorting:, luego imprime cada tarea. Ordena la lista usandosort(), imprime una línea vacía, luego imprimeAfter sorting:seguido de cada tarea nuevamente.
Debido a que tu clase Task implementa Comparable, puedes llamar a sort() directamente en la lista sin proporcionar un comparador personalizado. ¡Las tareas se organizarán automáticamente basándose en tu implementación de compareTo!
Salida esperada:
Before sorting:
Write report (Priority: 2)
Fix critical bug (Priority: 5)
Update documentation (Priority: 1)
Review code (Priority: 3)
After sorting:
Fix critical bug (Priority: 5)
Review code (Priority: 3)
Write report (Priority: 2)
Update documentation (Priority: 1)Hoja de referencia
La interfaz Comparable permite que los objetos definan un orden natural para la clasificación. Implementa Comparable<T> y sobrescribe el método compareTo.
El método compareTo devuelve:
- Un número negativo si
thisva antes queother - Cero si son iguales
- Un número positivo si
thisva después deother
Implementación básica (orden ascendente):
class Student implements Comparable<Student> {
String name;
int grade;
Student(this.name, this.grade);
@override
int compareTo(Student other) {
return grade.compareTo(other.grade);
}
}Una vez que una clase implementa Comparable, puedes usar sort() sin un comparador personalizado:
var students = [
Student('Alice', 85),
Student('Bob', 92),
Student('Carol', 78),
];
students.sort(); // Automatically uses compareToPara el orden descendente, invierte la comparación:
@override
int compareTo(Student other) {
return other.grade.compareTo(grade); // Descending
}Pruébalo tú mismo
import 'task.dart';
void main() {
// TODO: Crea una lista de objetos Task con lo siguiente:
// - 'Write report' con prioridad 2
// - 'Fix critical bug' con prioridad 5
// - 'Update documentation' con prioridad 1
// - 'Review code' con prioridad 3
List<Task> tasks = [
// TODO: Añade las cuatro tareas aquí
];
// TODO: Imprime "Before sorting:"
// TODO: Imprime cada tarea de la lista
// TODO: Ordena la lista usando sort()
// TODO: Imprime una línea vacía
// TODO: Imprime "After sorting:"
// TODO: Imprime cada tarea de la lista ordenada
}
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 Repository