Les opérateurs is et 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 la conversion échoue, une exception est levée. C’est pourquoi combiner is avec la promotion de type est souvent plus sûr que d’utiliser directement as. Vous pouvez également utiliser is! pour vérifier qu’un objet n’est pas d’un certain type.
Défi
FacileConstruisons 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
Shapeavec une propriétéString nameet un constructeur. Incluez une méthodedescribe()qui affiche'$name is a shape' - Une classe
Circlequi étendShapeavec une propriété supplémentairedouble radius. Ajoutez une méthodegetCircleInfo()qui affiche'Circle with radius: $radius' - Une classe
Rectanglequi étendShapeavec des propriétés supplémentairesdouble widthetdouble height. Ajoutez une méthodegetRectangleInfo()qui affiche'Rectangle: $width x $height'
- Une classe
main.dart: Importez votre fichier de formes et créez une fonctionprocessShape(Shape shape)qui :- Appelle d'abord
describe()sur la forme - Utilise
ispour vérifier si la forme est unCircle- si c'est le cas, utilisez la promotion de type pour appelergetCircleInfo() - Utilise
ispour vérifier si la forme est unRectangle- si c'est le cas, utilisez l'opérateuraspour la transtyper et appelergetRectangleInfo() - Utilise
is!pour vérifier si la forme n'est PAS unCircleet n'est PAS unRectangle- si c'est le cas, affichez'Unknown shape type'
main():- Créez un
Circlenommé'Round'avec un rayon de5.0et passez-le àprocessShape() - Affichez une ligne vide
- Créez un
Rectanglenommé'Box'avec une largeur de4.0et une hauteur de3.0et passez-le àprocessShape() - Affichez une ligne vide
- Créez une
Shapede base nommée'Mystery'et passez-la àprocessShape()
- Appelle d'abord
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 typeEssayez 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()
}
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
1Fondamentaux de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne