Menu
Coddy logo textTech

Les opérateurs is & as

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 60 sur 110.

Alors que runtimeType vous indique le type exact, Dart propose deux opérateurs qui sont plus pratiques pour la vérification de type et le transtypage : is et as.

L'opérateur is vérifie si un objet est d'un type spécifique et renvoie un booléen. Contrairement à runtimeType, il renvoie également true pour les types parents :

class Animal {}
class Dog extends Animal {}

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

Lorsque vous utilisez is à l'intérieur d'une instruction if, Dart promeut automatiquement le type, vous permettant d'accéder aux membres de la sous-classe sans transtypage explicite :

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart sait que animal est un Dog ici
    animal.bark();  // Peut appeler des méthodes spécifiques à Dog
  }
}

L'opérateur as convertit explicitement un objet en un type spécifique. Utilisez-le lorsque vous êtes certain du type :

Animal pet = Dog();
Dog myDog = pet as Dog;  // Conversion en Dog
myDog.bark();

Soyez prudent avec as - si le transtypage échoue, cela lève une exception. C'est pourquoi combiner is avec la promotion de type est souvent plus sûr que d'utiliser as directement. Vous pouvez également utiliser is! pour vérifier si un objet n'est pas d'un certain type.

challenge icon

Défi

Facile

Construisons un système de traitement de formes qui utilise les opérateurs is et as pour identifier et travailler avec différents types de formes. Vous allez créer une hiérarchie de formes et écrire des fonctions qui vérifient les types et accèdent en toute sécurité aux propriétés spécifiques aux types.

Vous organiserez votre code en deux fichiers :

  • shapes.dart : Définissez votre hiérarchie de formes ici :
    • Une classe Shape avec une propriété String name et un constructeur. Incluez une méthode describe() qui affiche '$name is a shape'
    • Une classe Circle qui étend Shape avec une propriété supplémentaire double radius. Ajoutez une méthode getCircleInfo() qui affiche 'Circle with radius: $radius'
    • Une classe Rectangle qui étend Shape avec des propriétés supplémentaires double width et double height. Ajoutez une méthode getRectangleInfo() qui affiche 'Rectangle: $width x $height'
  • main.dart : Importez votre fichier de formes et créez une fonction processShape(Shape shape) qui :
    • Appelle d'abord describe() sur la forme
    • Utilise is pour vérifier si la forme est un Circle - si c'est le cas, utilisez la promotion de type pour appeler getCircleInfo()
    • Utilise is pour vérifier si la forme est un Rectangle - si c'est le cas, utilisez l'opérateur as pour la transtyper et appeler getRectangleInfo()
    • Utilise is! pour vérifier si la forme n'est PAS un Circle et n'est PAS un Rectangle - si c'est le cas, affichez 'Unknown shape type'
    Ensuite, dans votre fonction main() :
    • Créez un Circle nommé 'Round' avec un rayon de 5.0 et passez-le à processShape()
    • Affichez une ligne vide
    • Créez un Rectangle nommé 'Box' avec une largeur de 4.0 et une hauteur de 3.0 et passez-le à processShape()
    • Affichez une ligne vide
    • Créez une Shape de base nommée 'Mystery' et passez-la à processShape()

Ce défi démontre les deux approches : l'utilisation de is avec la promotion de type automatique pour le Circle, et l'utilisation de as pour le transtypage explicite avec le Rectangle. Vous verrez également comment is! aide à identifier les formes qui ne correspondent à aucun sous-type spécifique.

Sortie attendue :

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

Aide-mémoire

L'opérateur is vérifie si un objet est d'un type spécifique et renvoie un booléen. Il renvoie également true pour les types parents :

class Animal {}
class Dog extends Animal {}

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

Lorsque vous utilisez is à l'intérieur d'une instruction if, Dart promeut automatiquement le type, vous permettant d'accéder aux membres de la sous-classe sans transtypage explicite :

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart sait que animal est un Dog ici
    animal.bark();  // Peut appeler des méthodes spécifiques à Dog
  }
}

L'opérateur as transtype explicitement un objet vers un type spécifique :

Animal pet = Dog();
Dog myDog = pet as Dog;  // Transtypage vers Dog
myDog.bark();

Soyez prudent avec as - si le transtypage échoue, il lève une exception. Combiner is avec la promotion de type est souvent plus sûr que d'utiliser as directement.

Utilisez is! pour vérifier si un objet n'est pas d'un certain type :

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

Essayez vous-même

import 'shapes.dart';

// TODO: Créer une fonction processShape(Shape shape) qui :
// 1. Appelle d'abord describe() sur la forme (shape)
// 2. Utilise 'is' pour vérifier si shape est un Circle - si c'est le cas, utilise la promotion de type pour appeler getCircleInfo()
// 3. Utilise 'is' pour vérifier si shape est un Rectangle - si c'est le cas, utilise l'opérateur 'as' pour transtyper et appeler getRectangleInfo()
// 4. Utilise 'is!' pour vérifier si shape n'est PAS un Circle et n'est PAS un Rectangle - si c'est le cas, affiche "Unknown shape type"

void main() {
  // TODO: Créer un Circle nommé 'Round' avec un rayon de 5.0 et le passer à processShape()
  
  // TODO: Afficher une ligne vide
  
  // TODO: Créer un Rectangle nommé 'Box' avec une largeur de 4.0 et une hauteur de 3.0 et le passer à processShape()
  
  // TODO: Afficher une ligne vide
  
  // TODO: Créer une Shape de base nommée 'Mystery' et la passer à processShape()
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet