Menu
Coddy logo textTech

Os Operadores is & as

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 60 de 110.

Enquanto o runtimeType informa o tipo exato, o Dart fornece dois operadores que são mais práticos para verificação de tipo e conversão (casting): is e as.

O operador is verifica se um objeto é de um tipo específico e retorna um booleano. Ao contrário do runtimeType, ele também retorna true para tipos pai:

class Animal {}
class Dog extends Animal {}

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

Quando você usa is dentro de uma instrução if, o Dart promove automaticamente o tipo, permitindo que você acesse membros da subclasse sem a necessidade de conversão explícita (casting):

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // O Dart sabe que animal é um Dog aqui
    animal.bark();  // Pode chamar métodos específicos de Dog
  }
}

O operador as converte explicitamente um objeto para um tipo específico. Use-o quando tiver certeza sobre o tipo:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Conversão para Dog
myDog.bark();

Tenha cuidado com as - se a conversão falhar, ela lançará uma exceção. É por isso que combinar is com promoção de tipo é frequentemente mais seguro do que usar as diretamente. Você também pode usar is! para verificar se um objeto não é de um determinado tipo.

challenge icon

Desafio

Fácil

Vamos construir um sistema de processamento de formas que utiliza os operadores is e as para identificar e trabalhar com diferentes tipos de formas. Você criará uma hierarquia de formas e escreverá funções que verificam tipos e acessam propriedades específicas de cada tipo com segurança.

Você organizará seu código em dois arquivos:

  • shapes.dart: Defina sua hierarquia de formas aqui:
    • Uma classe Shape com uma propriedade String name e um construtor. Inclua um método describe() que imprime '$name is a shape'
    • Uma classe Circle que estende Shape com uma propriedade adicional double radius. Adicione um método getCircleInfo() que imprime 'Circle with radius: $radius'
    • Uma classe Rectangle que estende Shape com propriedades adicionais double width e double height. Adicione um método getRectangleInfo() que imprime 'Rectangle: $width x $height'
  • main.dart: Importe seu arquivo de formas e crie uma função processShape(Shape shape) que:
    • Primeiro chama describe() na forma
    • Usa is para verificar se a forma é um Circle - se for, use a promoção de tipo para chamar getCircleInfo()
    • Usa is para verificar se a forma é um Rectangle - se for, use o operador as para fazer o cast e chamar getRectangleInfo()
    • Usa is! para verificar se a forma NÃO é um Circle e NÃO é um Rectangle - se for o caso, imprime 'Unknown shape type'
    Depois, em sua função main():
    • Crie um Circle chamado 'Round' com raio 5.0 e passe-o para processShape()
    • Imprima uma linha vazia
    • Crie um Rectangle chamado 'Box' com largura 4.0 e altura 3.0 e passe-o para processShape()
    • Imprima uma linha vazia
    • Crie uma Shape base chamada 'Mystery' e passe-a para processShape()

Este desafio demonstra ambas as abordagens: usar is com promoção automática de tipo para o Circle, e usar as para cast explícito com o Rectangle. Você também verá como is! ajuda a identificar formas que não correspondem a nenhum subtipo específico.

Saída 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

Folha de consulta

O operador is verifica se um objeto é de um tipo específico e retorna um booleano. Ele também retorna true para tipos pai:

class Animal {}
class Dog extends Animal {}

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

Quando você usa is dentro de uma instrução if, o Dart promove automaticamente o tipo, permitindo que você acesse membros da subclasse sem a necessidade de conversão explícita (casting):

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // O Dart sabe que animal é um Dog aqui
    animal.bark();  // Pode chamar métodos específicos de Dog
  }
}

O operador as converte explicitamente um objeto para um tipo específico:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Converte para Dog
myDog.bark();

Tenha cuidado com o as - se a conversão falhar, ele lançará uma exceção. Combinar is com a promoção de tipo (type promotion) geralmente é mais seguro do que usar as diretamente.

Use is! para verificar se um objeto não é de um determinado tipo:

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

Experimente você mesmo

import 'shapes.dart';

// TODO: Crie uma função processShape(Shape shape) que:
// 1. Primeiro chame describe() na forma (shape)
// 2. Use 'is' para verificar se shape é um Circle - se sim, use a promoção de tipo para chamar getCircleInfo()
// 3. Use 'is' para verificar se shape é um Rectangle - se sim, use o operador 'as' para fazer o cast e chamar getRectangleInfo()
// 4. Use 'is!' para verificar se shape NÃO é um Circle e NÃO é um Rectangle - se sim, imprima "Unknown shape type"

void main() {
  // TODO: Crie um Circle chamado 'Round' com radius 5.0 e passe-o para processShape()
  
  // TODO: Imprima uma linha vazia
  
  // TODO: Crie um Rectangle chamado 'Box' com width 4.0 e height 3.0 e passe-o para processShape()
  
  // TODO: Imprima uma linha vazia
  
  // TODO: Crie uma Shape base chamada 'Mystery' e passe-a para processShape()
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos