Menu
Coddy logo textTech

Gli operatori is e as

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 60 di 110.

Benché runtimeType ti indichi il tipo esatto, Dart fornisce due operatori più pratici per il controllo e la conversione dei tipi: is e as.

L’operatore is verifica se un oggetto è di un tipo specifico e restituisce un booleano. A differenza di runtimeType, restituisce true anche per i tipi genitori:

class Animal {}
class Dog extends Animal {}

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

Quando usi is all'interno di un'istruzione if, Dart promuove automaticamente il tipo, permettendoti di accedere ai membri della sottoclasse senza conversioni di tipo esplicite:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Qui Dart sa che animal è un Dog
    animal.bark();  // Può chiamare i metodi specifici di Dog
  }
}

L'operatore as esegue esplicitamente il cast di un oggetto a un tipo specifico. Usalo quando sei certo del tipo:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Esegui il cast a Dog
myDog.bark();

Fai attenzione a as: se la conversione di tipo fallisce, genera un’eccezione. Ecco perché spesso è più sicuro combinare is con la promozione del tipo invece di usare direttamente as. Puoi anche usare is! per verificare se un oggetto non è di un certo tipo.

challenge icon

Sfida

Facile

Costruiamo un sistema di elaborazione delle forme che usa gli operatori is e as per identificare e gestire diversi tipi di forme. Creerai una gerarchia di forme e scriverai funzioni che controllano i tipi e consentono di accedere in sicurezza alle proprietà specifiche di ciascun tipo.

Organizzerai il codice in due file:

  • shapes.dart: definisci qui la gerarchia delle forme:
    • Una classe Shape con una proprietà String name e un costruttore. Includi un metodo describe() che stampa [name] is a shape
    • Una classe Circle che estende Shape con una proprietà aggiuntiva double radius. Aggiungi un metodo getCircleInfo() che stampa Circle with radius: [radius]
    • Una classe Rectangle che estende Shape con le proprietà aggiuntive double width e double height. Aggiungi un metodo getRectangleInfo() che stampa Rectangle: [width] x [height]
  • main.dart: importa il file delle forme e crea una funzione processShape(Shape shape) che:
    • Per prima cosa chiama describe() sulla forma
    • Usa is per verificare se la forma è un Circle; in tal caso, usa la promozione automatica del tipo per chiamare getCircleInfo()
    • Usa is per verificare se la forma è un Rectangle; in tal caso, usa l'operatore as per eseguire il cast e chiamare getRectangleInfo()
    • Usa is! per verificare se la forma NON è un Circle e NON è un Rectangle; in tal caso, stampa Unknown shape type
    Poi, nella funzione main():
    • Crea un Circle di nome 'Round' con raggio 5.0 e passalo a processShape()
    • Stampa una riga vuota
    • Crea un Rectangle di nome 'Box' con larghezza 4.0 e altezza 3.0 e passalo a processShape()
    • Stampa una riga vuota
    • Crea una Shape di base di nome 'Mystery' e passala a processShape()

Questa sfida illustra entrambi gli approcci: usare is con la promozione automatica del tipo per il Circle e usare as per il cast esplicito con il Rectangle. Vedrai anche come is! aiuta a identificare le forme che non corrispondono ad alcun sottotipo specifico.

Output previsto:

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

Provalo tu

import 'shapes.dart';

// TODO: Crea una función processShape(Shape shape) que:
// 1. Primero llama a describe() sobre la figura
// 2. Usa 'is' para comprobar si shape es un Circle; si es así, usa la promoción de tipos para llamar a getCircleInfo()
// 3. Usa 'is' para comprobar si shape es un Rectangle; si es así, usa el operador 'as' para hacer una conversión de tipo y llamar a getRectangleInfo()
// 4. Usa 'is!' para comprobar si shape NO es un Circle NI un Rectangle; si es así, imprime "Unknown shape type"

void main() {
  // TODO: Crea un Circle llamado 'Round' con radio 5.0 y pásalo a processShape()
  
  // TODO: Imprime una línea vacía
  
  // TODO: Crea un Rectangle llamado 'Box' con ancho 4.0 y alto 3.0, y pásalo a processShape()
  
  // TODO: Imprime una línea vacía
  
  // TODO: Crea un Shape base llamado 'Mystery' y pásalo a processShape()
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online