Os operadores is e 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.
Desafio
FácilVamos criar um sistema de processamento de formas que usa 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 com segurança propriedades específicas de cada tipo.
Você organizará seu código em dois arquivos:
shapes.dart: Defina sua hierarquia de formas aqui:- Uma classe
Shapecom uma propriedadeString namee um construtor. Inclua um métododescribe()que imprime[name] is a shape - Uma classe
Circleque estendeShapecom uma propriedade adicionaldouble radius. Adicione um métodogetCircleInfo()que imprimeCircle with radius: [radius] - Uma classe
Rectangleque estendeShapecom as propriedades adicionaisdouble widthedouble height. Adicione um métodogetRectangleInfo()que imprimeRectangle: [width] x [height]
- Uma classe
main.dart: Importe seu arquivo de formas e crie uma funçãoprocessShape(Shape shape)que:- Primeiro chama
describe()na forma - Usa
ispara verificar se a forma é umCircle— nesse caso, use a promoção de tipo para chamargetCircleInfo() - Usa
ispara verificar se a forma é umRectangle— nesse caso, use o operadoraspara fazer a conversão de tipo e chamargetRectangleInfo() - Usa
is!para verificar se a forma NÃO é umCirclee NÃO é umRectangle— nesse caso, imprimaUnknown shape type
main():- Crie um
Circlechamado'Round'com raio5.0e passe-o paraprocessShape() - Imprima uma linha vazia
- Crie um
Rectanglechamado'Box'com largura4.0e altura3.0e passe-o paraprocessShape() - Imprima uma linha vazia
- Crie uma
Shapebase chamada'Mystery'e passe-a paraprocessShape()
- Primeiro chama
Este desafio demonstra as duas abordagens: usar is com promoção automática de tipo para o Circle e usar as para a conversão explícita de tipo 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 typeExperimente 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()
}
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
1Fundamentos de OOP
Arquivos externosBibliotecas e importsIntrodução à OOPClasses vs. objetosA palavra-chave thisMétodosVariáveis de instânciaNoções básicas de construtoresRevisão - Calculadora simples4Segurança contra nulos
Introdução à segurança contra nulosAnulável vs. não anulávelOs operadores ? e !Palavra-chave Late e segurança contra nulosOperadores conscientes de nulosSegurança contra nulos em classesRecapitulação — Sistema de perfil de usuário7Classes Abstratas e Interfaces
Classes AbstratasMétodos AbstratosInterfaces em DartInterfaces ImplícitasImplementação vs. ExtensãoMúltiplas InterfacesRecapitulação - Calculadora de Formas10Coleções e Genéricos
Visão geral de List, Set e MapColeções com segurança de tiposClasses genéricasMétodos genéricosRestrições genéricasIterable e IteratorRecapitulação - Armazenamento genérico13Conceitos Avançados de OOP
Composição vs. HerançaMétodos de ExtensãoClasses ChamáveisClasses Seladas (Dart 3)Registros (Dart 3)Padrões e Correspondência (3.0)Enums com Métodos16Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários2Construtores em Dart
Construtor padrãoConstrutores nomeadosListas de inicializaçãoConstrutores constantesConstrutores factoryConstrutores de redirecionamentoRevisão - Construtor de formas5Encapsulamento
Membros Públicos vs. PrivadosConvenção do Prefixo _Privacidade no Nível da BibliotecaAprofundamento em Getters e SettersOcultação de InformaçõesRecapitulação - Registros de Alunos8Mixins
Introdução a MixinsCriando MixinsUsando vários MixinsPalavra-chave on em MixinsMixin vs HerançaMixin vs InterfaceRecapitulação - Sistema de Animais11Métodos Especiais
Sobrescrita de toString()Sobrescrita de hashCode e ==Interface ComparableMétodo call()Sobrescrita de noSuchMethodRecapitulação - Coleção Personalizada14Padrões de Projeto – Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy3Propriedades de Classe
Membros de Instância vs. EstáticosCampos Final e ConstVariáveis LateMétodos e Campos EstáticosGetters e SettersRecapitulação - Gerenciador de Contas Bancárias6Herança
Herança BásicaA Palavra-chave superSobrescrita de MétodosA Anotação @overrideA Palavra-chave final para ClassesConstrutores e HerançaRecapitulação - Hierarquia de Funcionários9Polimorfismo
Fundamentos do polimorfismoPolimorfismo por meio de interfacesVerificação de tipos em tempo de execuçãoOs operadores is e asPalavra-chave covarianteRecapitulação — Processador de pagamentos12OOP Assíncrona
Futures e async/awaitNoções básicas de StreamsControladores de StreamConstrutores assíncronosAsync em métodos de classeRecapitulação — Buscador de dados15Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão RepositoryPratique por conta própria: Compilador de Dart online