Menu
Coddy logo textTech

Los operadores is y as

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

Mientras que runtimeType te indica el tipo exacto, Dart proporciona dos operadores que son más prácticos para la comprobación de tipos y la conversión: is y as.

El operador is comprueba si un objeto es de un tipo específico y devuelve un booleano. A diferencia de runtimeType, también devuelve true para tipos padre:

class Animal {}
class Dog extends Animal {}

void main() {
  Animal pet = Dog();
  
  print(pet is Dog);     // true
  print(pet is Animal);  // true (Dog ES un Animal)
  print(pet is String);  // false
}

Cuando usas is dentro de una sentencia if, Dart promueve automáticamente el tipo, permitiéndote acceder a los miembros de la subclase sin un casting explícito:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart sabe que animal es un Dog aquí
    animal.bark();  // Puede llamar a métodos específicos de Dog
  }
}

El operador as realiza una conversión explícita (cast) de un objeto a un tipo específico. Úsalo cuando estés seguro del tipo:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Convertir a Dog
myDog.bark();

Ten cuidado con as: si la conversión falla, lanza una excepción. Por eso, combinar is con la promoción de tipos suele ser más seguro que usar as directamente. También puedes usar is! para comprobar si un objeto no es de un tipo determinado.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de procesamiento de formas que utiliza los operadores is y as para identificar y trabajar con diferentes tipos de formas. Crearás una jerarquía de formas y escribirás funciones que verifiquen tipos y accedan de forma segura a propiedades específicas de cada tipo.

Organizarás tu código en dos archivos:

  • shapes.dart: Define tu jerarquía de formas aquí:
    • Una clase Shape con una propiedad String name y un constructor. Incluye un método describe() que imprima '$name is a shape'
    • Una clase Circle que extienda de Shape con una propiedad adicional double radius. Añade un método getCircleInfo() que imprima 'Circle with radius: $radius'
    • Una clase Rectangle que extienda de Shape con propiedades adicionales double width y double height. Añade un método getRectangleInfo() que imprima 'Rectangle: $width x $height'
  • main.dart: Importa tu archivo de formas y crea una función processShape(Shape shape) que:
    • Primero llame a describe() en la forma
    • Use is para verificar si la forma es un Circle; si es así, usa la promoción de tipos para llamar a getCircleInfo()
    • Use is para verificar si la forma es un Rectangle; si es así, usa el operador as para realizar un casting y llamar a getRectangleInfo()
    • Use is! para verificar si la forma NO es un Circle y NO es un Rectangle; si es así, imprime 'Unknown shape type'
    Luego, en tu función main():
    • Crea un Circle llamado 'Round' con un radio de 5.0 y pásalo a processShape()
    • Imprime una línea vacía
    • Crea un Rectangle llamado 'Box' con un ancho de 4.0 y una altura de 3.0 y pásalo a processShape()
    • Imprime una línea vacía
    • Crea una Shape base llamada 'Mystery' y pásala a processShape()

Este desafío demuestra ambos enfoques: usar is con promoción automática de tipos para el Circle, y usar as para un casting explícito con el Rectangle. También verás cómo is! ayuda a identificar formas que no coinciden con ningún subtipo específico.

Salida esperada:

Round is a shape
Circle with radius: 5.0

Box is a shape
Rectangle: 4.0 x 3.0

Mystery is a shape
Unknown shape type

Hoja de referencia

El operador is comprueba si un objeto es de un tipo específico y devuelve un booleano. También devuelve true para los tipos padre:

class Animal {}
class Dog extends Animal {}

void main() {
  Animal pet = Dog();
  
  print(pet is Dog);     // true
  print(pet is Animal);  // true (Dog ES un Animal)
  print(pet is String);  // false
}

Cuando usas is dentro de una sentencia if, Dart promueve automáticamente el tipo, permitiéndote acceder a los miembros de la subclase sin un casting explícito:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart sabe que animal es un Dog aquí
    animal.bark();  // Puede llamar a métodos específicos de Dog
  }
}

El operador as realiza un casting explícito de un objeto a un tipo específico:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Casting a Dog
myDog.bark();

Ten cuidado con as: si el casting falla, lanza una excepción. Combinar is con la promoción de tipos suele ser más seguro que usar as directamente.

Usa is! para comprobar si un objeto no es de un tipo determinado:

if (animal is! Dog) {
  print("Not a dog");
}

Pruébalo tú mismo

import 'shapes.dart';

// TODO: Crea una función processShape(Shape shape) que:
// 1. Primero llame a describe() en la forma (shape)
// 2. Use 'is' para verificar si shape es un Circle; si es así, usa la promoción de tipos para llamar a getCircleInfo()
// 3. Use 'is' para verificar si shape es un Rectangle; si es así, usa el operador 'as' para realizar el cast y llamar a getRectangleInfo()
// 4. Use 'is!' para verificar si shape NO es un Circle y NO es un Rectangle; si es así, imprime "Unknown shape type"

void main() {
  // TODO: Crea un Circle llamado 'Round' con un radio de 5.0 y pásalo a processShape()
  
  // TODO: Imprime una línea vacía
  
  // TODO: Crea un Rectangle llamado 'Box' con un ancho de 4.0 y una altura de 3.0 y pásalo a processShape()
  
  // TODO: Imprime una línea vacía
  
  // TODO: Crea una Shape base llamada 'Mystery' y pásala a processShape()
}
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