Menu
Coddy logo textTech

Palabra clave on en Mixins

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 53 de 110.

A veces, un mixin necesita usar métodos o propiedades de la clase en la que se mezcla. La palabra clave on te permite restringir un mixin para que solo se use con clases que extienden un tipo específico.

class Animal {
  String name;
  Animal(this.name);
  
  void breathe() => print('$name is breathing');
}

mixin Swimming on Animal {
  void swim() {
    print('$name is swimming');  // Puede acceder a 'name' desde Animal
    breathe();  // Puede llamar a los métodos de Animal
  }
}

class Fish extends Animal with Swimming {
  Fish(String name) : super(name);
}

La declaración on Animal significa que este mixin solo puede aplicarse a clases que extiendan Animal. Esto garantiza que el mixin tenga acceso a los miembros de Animal. Sin on, el mixin no sabría que name o breathe() existen.

Si intentas usar un mixin restringido en una clase incompatible, Dart te da un error en tiempo de compilación:

class Robot with Swimming {}  // ¡Error! Robot no extiende Animal

Esta restricción es útil cuando la funcionalidad de tu mixin depende de capacidades específicas de una clase base. Crea un contrato más seguro: el mixin promete cierto comportamiento, pero solo cuando tiene la base que necesita para funcionar correctamente.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de vehículos que demuestre cómo la palabra clave on restringe los mixins para que funcionen solo con clases base específicas. Crearás un mixin que añade la funcionalidad de turbo boost, pero solo podrá ser utilizado por clases que extiendan una clase base Vehicle.

Organizarás tu código en dos archivos:

  • vehicles.dart: Define aquí tu clase base, el mixin restringido y los tipos de vehículos:
    • Una clase Vehicle con una propiedad String model y una propiedad int speed. Incluye un constructor que reciba ambos valores. Añade un método accelerate() que imprima '$model accelerating to $speed km/h'
    • Un mixin TurboBoost restringido a Vehicle usando la palabra clave on. Este mixin debe tener un método activateTurbo() que imprima '$model TURBO ACTIVATED!' y luego llame a accelerate() (ambos accesibles debido a la restricción on Vehicle)
    • Una clase SportsCar que extienda Vehicle y use el mixin TurboBoost. Añade una propiedad String color. El constructor debe recibir model, speed y color. Incluye un método showOff() que imprima '$color $model ready to race!'
  • main.dart: Importa tu archivo de vehículos y demuestra cómo funciona el mixin restringido:
    • Crea un SportsCar con model 'Ferrari', speed 320 y color 'Red'
    • Llama a showOff()
    • Llama a activateTurbo()

El mixin TurboBoost puede acceder a model y llamar a accelerate() porque la declaración on Vehicle garantiza que solo se mezclará en clases que extiendan Vehicle. Esto crea un contrato seguro donde el mixin sabe exactamente qué capacidades están disponibles.

Salida esperada:

Red Ferrari ready to race!
Ferrari TURBO ACTIVATED!
Ferrari accelerating to 320 km/h

Hoja de referencia

La palabra clave on restringe un mixin para que solo se use con clases que extienden un tipo específico. Esto permite que el mixin acceda de forma segura a los métodos y propiedades de la clase base.

class Animal {
  String name;
  Animal(this.name);
  
  void breathe() => print('$name is breathing');
}

mixin Swimming on Animal {
  void swim() {
    print('$name is swimming');  // Can access 'name' from Animal
    breathe();  // Can call Animal's methods
  }
}

class Fish extends Animal with Swimming {
  Fish(String name) : super(name);
}

La declaración on Animal garantiza que el mixin tenga acceso a los miembros de Animal. Sin ella, el mixin no sabría que name o breathe() existen.

Intentar usar un mixin restringido en una clase incompatible resulta en un error de tiempo de compilación:

class Robot with Swimming {}  // Error! Robot doesn't extend Animal

Esta restricción es útil cuando la funcionalidad de su mixin depende de capacidades específicas de una clase base, creando un contrato más seguro entre el mixin y las clases que lo utilizan.

Pruébalo tú mismo

import 'vehicles.dart';

void main() {
  // TODO: Crear un SportsCar con el modelo 'Ferrari', velocidad 320 y color 'Red'
  
  // TODO: Llamar a showOff()
  
  // TODO: Llamar a activateTurbo()
}
quiz iconPonte a prueba

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