Sobrescritura de toString()
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 70 de 110.
Cuando imprimes un objeto en Dart, es posible que veas algo como Instance of 'Person' - no es muy útil. Esto sucede porque cada clase hereda un método toString() predeterminado de Object que solo devuelve el nombre de la clase.
Al sobrescribir toString(), puedes proporcionar una representación de cadena significativa de tus objetos:
class Person {
String name;
int age;
Person(this.name, this.age);
@override
String toString() {
return 'Person(name: $name, age: $age)';
}
}
void main() {
var person = Person('Alice', 30);
print(person); // Person(name: Alice, age: 30)
}Sin la sobrescritura, print(person) mostraría Instance of 'Person'. Con ella, obtienes información útil sobre el estado del objeto.
El método toString() se llama automáticamente cada vez que Dart necesita convertir tu objeto en una cadena; en sentencias print(), interpolación de cadenas o al concatenar con otras cadenas:
var message = 'User: $person'; // toString() se llama automáticamente
print('Found: ' + person.toString()); // Llamada explícitaUn toString() bien implementado facilita mucho la depuración al permitirte inspeccionar rápidamente los valores de los objetos durante el desarrollo.
Desafío
FácilVamos a construir un sistema de catálogo de productos donde cada producto muestre su información en un formato limpio y legible al ser impreso. Practicarás la sobrescritura del método toString() para hacer que tus objetos sean más fáciles de depurar y amigables para el usuario.
Organizarás tu código en dos archivos:
product.dart: Crea una claseProductque represente un artículo en una tienda. Tu producto debe tener unname(String),price(double) yquantity(int). Sobrescribe el métodotoString()para devolver una cadena formateada exactamente en este formato:Product(name: [name], price: $[price], qty: [quantity])main.dart: Importa tu archivo de producto y demuestra cómo la sobrescritura detoString()hace que la impresión de objetos sea mucho más útil. Crea tres productos e imprímelos para ver tu representación de cadena personalizada en acción:- Un producto llamado
'Laptop'con precio999.99y cantidad5 - Un producto llamado
'Mouse'con precio29.5y cantidad50 - Un producto llamado
'Keyboard'con precio75.0y cantidad30
Featured: [product]usando el producto Laptop.- Un producto llamado
Observa cómo imprimir cada producto directamente muestra información significativa en lugar del mensaje poco útil Instance of 'Product'. Tu método toString() se llama automáticamente tanto en las sentencias print() como al usar la interpolación de cadenas.
Salida esperada:
Product(name: Laptop, price: $999.99, qty: 5)
Product(name: Mouse, price: $29.5, qty: 50)
Product(name: Keyboard, price: $75.0, qty: 30)
Featured: Product(name: Laptop, price: $999.99, qty: 5)Pruébalo tú mismo
import 'product.dart';
void main() {
// TODO: Crea tres instancias de Product:
// 1. Laptop - price: 999.99, quantity: 5
// 2. Mouse - price: 29.5, quantity: 50
// 3. Keyboard - price: 75.0, quantity: 30
// TODO: Imprime cada producto (se llamará a toString() automáticamente)
// TODO: Imprime un mensaje destacado usando interpolación de cadenas
// Formato: Featured: [laptop product]
}
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