Menu
Coddy logo textTech

is 및 as 연산자

Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 60번째.

runtimeType이 정확한 타입을 알려주지만, Dart는 타입 검사와 캐스팅에 더 실용적인 두 가지 연산자인 isas를 제공합니다.

is 연산자는 객체가 특정 타입인지 확인하고 불리언을 반환합니다. runtimeType과 달리, 부모 타입에 대해서도 true를 반환합니다:

class Animal {}
class Dog extends Animal {}

void main() {
  Animal pet = Dog();
  
  print(pet is Dog);     // true
  print(pet is Animal);  // true (Dog은 Animal입니다)
  print(pet is String);  // false
}

if 문 안에서 is를 사용하면, Dart는 자동으로 타입을 승격(promote)시켜 명시적인 캐스팅 없이도 서브클래스의 멤버에 접근할 수 있게 해줍니다:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // 여기서 Dart는 animal이 Dog라는 것을 압니다
    animal.bark();  // Dog 전용 메서드를 호출할 수 있습니다
  }
}

as 연산자는 객체를 특정 타입으로 명시적으로 형변환합니다. 타입에 대해 확신이 있을 때 사용하세요:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Dog으로 형변환
myDog.bark();

as 사용 시 주의하세요 - 캐스트에 실패하면 예외가 발생합니다. 그래서 is를 타입 프로모션과 결합하는 것이 as를 직접 사용하는 것보다 대개 더 안전합니다. 또한 is!를 사용하여 객체가 특정 타입이 아닌지 확인할 수 있습니다.

challenge icon

챌린지

쉬움

isas 연산자를 사용하여 다양한 도형 타입을 식별하고 작업하는 도형 처리 시스템을 구축해 보겠습니다. 도형 계층 구조를 만들고 타입을 확인하며 타입별 속성에 안전하게 접근하는 함수를 작성하게 됩니다.

코드를 두 개의 파일로 구성합니다:

  • shapes.dart: 여기에 도형 계층 구조를 정의합니다:
    • String name 속성과 생성자를 가진 Shape 클래스. '[name] is a shape'를 출력하는 describe() 메서드를 포함합니다.
    • Shape를 상속받고 double radius 속성이 추가된 Circle 클래스. 'Circle with radius: [radius]'를 출력하는 getCircleInfo() 메서드를 추가합니다.
    • Shape를 상속받고 double widthdouble height 속성이 추가된 Rectangle 클래스. 'Rectangle: [width] x [height]'를 출력하는 getRectangleInfo() 메서드를 추가합니다.
  • main.dart: 도형 파일을 임포트하고 다음을 수행하는 processShape(Shape shape) 함수를 만듭니다:
    • 먼저 도형의 describe()를 호출합니다.
    • is를 사용하여 도형이 Circle인지 확인합니다. 맞다면 타입 프로모션(type promotion)을 사용하여 getCircleInfo()를 호출합니다.
    • is를 사용하여 도형이 Rectangle인지 확인합니다. 맞다면 as 연산자를 사용하여 캐스팅하고 getRectangleInfo()를 호출합니다.
    • is!를 사용하여 도형이 Circle이 아니고 Rectangle도 아닌지 확인합니다. 맞다면 'Unknown shape type'을 출력합니다.
    그 다음 main() 함수에서:
    • 이름이 'Round'이고 반지름이 5.0Circle을 생성하여 processShape()에 전달합니다.
    • 빈 줄을 출력합니다.
    • 이름이 'Box'이고 너비가 4.0, 높이가 3.0Rectangle을 생성하여 processShape()에 전달합니다.
    • 빈 줄을 출력합니다.
    • 이름이 'Mystery'인 기본 Shape를 생성하여 processShape()에 전달합니다.

이 챌린지는 두 가지 접근 방식을 모두 보여줍니다: Circle에 대해 자동 타입 프로모션과 함께 is를 사용하는 방식과 Rectangle에 대해 명시적 캐스팅을 위해 as를 사용하는 방식입니다. 또한 is!가 특정 서브타입과 일치하지 않는 도형을 식별하는 데 어떻게 도움이 되는지도 확인할 수 있습니다.

예상 출력:

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

치트 시트

is 연산자는 객체가 특정 타입인지 확인하고 불리언(boolean)을 반환합니다. 또한 부모 타입에 대해서도 true를 반환합니다:

class Animal {}
class Dog extends Animal {}

void main() {
  Animal pet = Dog();
  
  print(pet is Dog);     // true
  print(pet is Animal);  // true (Dog은 Animal입니다)
  print(pet is String);  // false
}

if 문 안에서 is를 사용하면, Dart가 자동으로 타입을 변환(type promotion)하여 명시적인 캐스팅 없이도 하위 클래스의 멤버에 접근할 수 있게 해줍니다:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart는 여기서 animal이 Dog임을 압니다
    animal.bark();  // Dog 전용 메서드를 호출할 수 있습니다
  }
}

as 연산자는 객체를 특정 타입으로 명시적으로 캐스팅합니다:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Dog으로 캐스팅
myDog.bark();

as를 사용할 때는 주의해야 합니다. 캐스팅에 실패하면 예외(exception)가 발생합니다. is와 타입 변환을 결합하는 것이 as를 직접 사용하는 것보다 대개 더 안전합니다.

객체가 특정 타입이 아닌지 확인하려면 is!를 사용하세요:

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

직접 해보기

import 'shapes.dart';

// TODO: 다음을 수행하는 processShape(Shape shape) 함수를 만드세요:
// 1. 먼저 shape에 대해 describe()를 호출합니다.
// 2. 'is'를 사용하여 shape이 Circle인지 확인합니다 - 만약 그렇다면, 타입 프로모션을 사용하여 getCircleInfo()를 호출합니다.
// 3. 'is'를 사용하여 shape이 Rectangle인지 확인합니다 - 만약 그렇다면, 'as' 연산자를 사용하여 캐스팅하고 getRectangleInfo()를 호출합니다.
// 4. 'is!'를 사용하여 shape이 Circle이 아니고 Rectangle도 아닌지 확인합니다 - 만약 그렇다면, "Unknown shape type"을 출력합니다.

void main() {
  // TODO: 반지름이 5.0인 'Round'라는 이름의 Circle을 생성하고 processShape()에 전달하세요.
  
  // TODO: 빈 줄을 출력하세요.
  
  // TODO: 너비가 4.0이고 높이가 3.0인 'Box'라는 이름의 Rectangle을 생성하고 processShape()에 전달하세요.
  
  // TODO: 빈 줄을 출력하세요.
  
  // TODO: 'Mystery'라는 이름의 기본 Shape을 생성하고 processShape()에 전달하세요.
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨