Menu
Coddy logo textTech

The is & as Operators

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 60 of 110.

While runtimeType tells you the exact type, Dart provides two operators that are more practical for type checking and casting: is and as.

The is operator checks whether an object is of a specific type and returns a boolean. Unlike runtimeType, it also returns true for parent types:

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
}

When you use is inside an if statement, Dart automatically promotes the type, letting you access subclass members without explicit casting:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart knows animal is a Dog here
    animal.bark();  // Can call Dog-specific methods
  }
}

The as operator explicitly casts an object to a specific type. Use it when you're certain about the type:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Cast to Dog
myDog.bark();

Be careful with as - if the cast fails, it throws an exception. That's why combining is with type promotion is often safer than using as directly. You can also use is! to check if an object is not of a certain type.

challenge icon

Challenge

Easy

Let's build a shape processing system that uses the is and as operators to identify and work with different shape types. You'll create a hierarchy of shapes and write functions that check types and safely access type-specific properties.

You'll organize your code into two files:

  • shapes.dart: Define your shape hierarchy here:
    • A Shape class with a String name property and a constructor. Include a method describe() that prints [name] is a shape
    • A Circle class that extends Shape with an additional double radius property. Add a method getCircleInfo() that prints Circle with radius: [radius]
    • A Rectangle class that extends Shape with additional double width and double height properties. Add a method getRectangleInfo() that prints Rectangle: [width] x [height]
  • main.dart: Import your shapes file and create a function processShape(Shape shape) that:
    • First calls describe() on the shape
    • Uses is to check if the shape is a Circle - if so, use type promotion to call getCircleInfo()
    • Uses is to check if the shape is a Rectangle - if so, use the as operator to cast it and call getRectangleInfo()
    • Uses is! to check if the shape is NOT a Circle and NOT a Rectangle - if so, print Unknown shape type
    Then in your main() function:
    • Create a Circle named 'Round' with radius 5.0 and pass it to processShape()
    • Print an empty line
    • Create a Rectangle named 'Box' with width 4.0 and height 3.0 and pass it to processShape()
    • Print an empty line
    • Create a base Shape named 'Mystery' and pass it to processShape()

This challenge demonstrates both approaches: using is with automatic type promotion for the Circle, and using as for explicit casting with the Rectangle. You'll also see how is! helps identify shapes that don't match any specific subtype.

Expected output:

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

Cheat sheet

The is operator checks whether an object is of a specific type and returns a boolean. It also returns true for parent types:

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
}

When you use is inside an if statement, Dart automatically promotes the type, letting you access subclass members without explicit casting:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart knows animal is a Dog here
    animal.bark();  // Can call Dog-specific methods
  }
}

The as operator explicitly casts an object to a specific type:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Cast to Dog
myDog.bark();

Be careful with as - if the cast fails, it throws an exception. Combining is with type promotion is often safer than using as directly.

Use is! to check if an object is not of a certain type:

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

Try it yourself

import 'shapes.dart';

// TODO: Create a function processShape(Shape shape) that:
// 1. First calls describe() on the shape
// 2. Uses 'is' to check if shape is a Circle - if so, use type promotion to call getCircleInfo()
// 3. Uses 'is' to check if shape is a Rectangle - if so, use 'as' operator to cast and call getRectangleInfo()
// 4. Uses 'is!' to check if shape is NOT a Circle and NOT a Rectangle - if so, print "Unknown shape type"

void main() {
  // TODO: Create a Circle named 'Round' with radius 5.0 and pass it to processShape()
  
  // TODO: Print an empty line
  
  // TODO: Create a Rectangle named 'Box' with width 4.0 and height 3.0 and pass it to processShape()
  
  // TODO: Print an empty line
  
  // TODO: Create a base Shape named 'Mystery' and pass it to processShape()
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming