Lección 1 · 1 de 20
Clases y listas de inicialización · Dart
Defina clases en Dart con campos final, constructores abreviados con this y listas de inicialización que preparan los datos antes del cuerpo.

Una clase agrupa datos y comportamiento. Product tiene tres campos `final`: se asignan una vez, al construir el objeto, y ya no cambian, que es lo habitual en Dart para los objetos que representan datos. El precio se guarda en céntimos (priceCents), un entero, para no arrastrar errores de redondeo.
El constructor Product(this.name, this.priceCents, {this.stock = 0}) usa parámetros formales de inicialización: this.name copia el argumento directamente en el campo, sin escribir ninguna asignación. stock es un parámetro con nombre con valor por defecto, por eso cable sale con 0 in stock. El getter label compone el texto a partir de los campos.
Invoice necesita algo más: guardar el cliente limpio y calcular el total. Como esos campos son final, no se pueden asignar dentro del cuerpo del constructor; para eso está la lista de inicialización, lo que va detrás de los dos puntos. customer = customer.trim().toUpperCase() asigna el campo a partir del parámetro del mismo nombre, y totalCents suma los precios de las líneas con fold.
Las inicializaciones se ejecutan en orden y antes del cuerpo entre llaves. Cuando el cuerpo se ejecuta, el objeto ya está completo: por eso puede escribir this.customer, el campo ya en mayúsculas (GARCIA LTD), y no customer, que dentro del constructor es el parámetro, todavía con espacios. Observe que number usa la forma corta this.number y convive sin problema con la lista de inicialización.
Código · main.dart
// A product in a shop catalogue.class Product { final String name; final int priceCents; final int stock; // this.name copies the argument straight into the field. Product(this.name, this.priceCents, {this.stock = 0}); String get label => '$name - ${(priceCents / 100).toStringAsFixed(2)} EUR';}class Invoice { final String number; final String customer; final int totalCents; // The initializer list (after the colon) sets final fields // before the constructor body runs. Invoice(this.number, String customer, List<Product> lines) : customer = customer.trim().toUpperCase(), totalCents = lines.fold(0, (sum, p) => sum + p.priceCents) { print('Invoice $number ready for ${this.customer}'); }}void main() { final mouse = Product('Wireless mouse', 1999, stock: 25); final cable = Product('USB-C cable', 899); print(mouse.label); print('${cable.name}: ${cable.stock} in stock'); final invoice = Invoice('INV-0042', ' Garcia Ltd ', [mouse, cable]); print('Total: ${invoice.totalCents} cents');}Salida · dart run main.dart
Wireless mouse - 19.99 EUR USB-C cable: 0 in stock Invoice INV-0042 ready for GARCIA LTD Total: 2898 cents
Para recordar
- Los campos
finalse asignan una sola vez, al construir el objeto. this.campoen los parámetros copia el argumento en el campo.- La lista de inicialización (
: campo = ...) se ejecuta antes del cuerpo. - Dentro del constructor,
this.xes el campo yxes el parámetro. - Guarde el dinero en céntimos enteros para evitar errores de redondeo.
Ejercicio
Añada a Invoice un campo final int lineCount que se calcule en la lista de inicialización con lines.length, y escríbalo junto al total.