Dart 오답노트 38 : Map, Object, 다형성(Polymorphism)

샤워실의 바보·2023년 12월 4일
0
post-thumbnail

Dart 언어에서 MapObject는 기본적인 유형이지만, 각각 다른 목적과 특성을 가지고 있습니다:

Map

  1. 정의: Map은 키-값 쌍의 모음입니다. 다른 언어에서 사전, 해시 또는 연관 배열이라고 하는 것과 유사합니다.

  2. 사용법:

    • 키-값 쌍의 형태로 데이터를 저장하는 데 사용됩니다.
    • Map 내의 각 키는 고유해야 하며, 하나의 키는 정확히 하나의 값을 매핑합니다.
    • Map의 키와 값은 어떤 타입이든 될 수 있습니다.
  3. 특징:

    • 키를 기반으로 빠른 조회, 추가, 삭제를 제공합니다.
    • add, remove, containsKey, forEach 등의 다양한 데이터 조작 방법을 제공합니다.
    • Dart는 변경 가능한 Map과 불변 Map 타입을 모두 제공합니다.
  4. 예시:

    var map = {'first': 'Dart', 'second': 'Flutter'};
    print(map['first']); // 출력: Dart
  5. 사용 사례: 데이터가 자연스럽게 키-값 쌍으로 구조화된 시나리오에 이상적입니다. 예를 들어, 설정, 사전 구현, 값의 집합에서 다른 집합으로의 매핑 등에서 사용됩니다.

Object

  1. 정의: Object는 모든 Dart 클래스의 기본 클래스입니다. String, int와 같은 내장 타입과 사용자 정의 클래스를 포함한 모든 다른 클래스는 Object의 하위 클래스입니다.

  2. 사용법:

    • 다른 상위 클래스가 명시되지 않은 경우 기본적으로 상속됩니다.
    • 모든 Dart 객체에 공통적인 기본 동작을 제공합니다. 예를 들어, 런타임 타입 정보, 일반 객체로 전달될 수 있는 능력 등이 있습니다.
  3. 특징:

    • toString(), hashCode, runtimeType, == 연산자와 같은 메서드가 모든 Dart 객체에 포함되어 있습니다.
    • 다형성을 허용합니다. 어떤 Dart 객체든 Object로 취급될 수 있습니다.
  4. 예시:

    class MyClass {
      // 이 클래스는 암묵적으로 Object를 상속
    }
    
    var myObject = MyClass();
    print(myObject.runtimeType); // 출력: MyClass
  5. 사용 사례: Dart에서 보편적인 타입으로 사용됩니다. 어떤 타입이든 처리할 수 있는 일반적인 코드를 작성하거나, 하위 클래스에서 재정의할 수 있는 공통 동작을 정의하는 데 유용합니다.

주요 차이점

  • 성격: Map은 키-값 쌍을 위한 컬렉션 타입이며, Object는 Dart 클래스 계층의 루트입니다.
  • 목적: Map은 키-값 형식으로 데이터를 구조화하여 저장 및 검색하는 데 사용됩니다. Object는 모든 Dart 클래스에 공통 기능을 제공하는 기본 클래스로 사용됩니다.
  • 유연성: Map은 저장할 수 있는 키-값 쌍의 타입과 수에 있어서 유연합니다. 반면 Object는 클래스의 단일 인스턴스를 나타내며, 다양한 속성과 메서드를 가질 수 있습니다.
  • 메서드 및 속성: Map에는 키-값 쌍 조작과 관련된 특정 메서드가 있으며, Object에는 모든 Dart 객체에 공통적인 메서드와 속성이 있습니다.

요약하자면, Dart에서 MapObject는 근본적으로 다릅니다. Map은 키-값 쌍을 위한 컬렉션 타입이고, Object는 모든 Dart 클래스의 기본 클래스로, 일련의 공통 기능을 제공합니다.

객체 지향 프로그래밍(OOP)에서 다형성은 서로 다른 클래스의 객체들이 공통의 상위 클래스의 객체로 취급될 수 있게 해주는 핵심 개념입니다. "다형성"이라는 용어는 "많은 형태"를 의미하는 그리스어에서 유래했습니다. 다형성에 대해 자세히 알아보겠습니다:

다형성의 유형

  1. 컴파일 시간 다형성 (메서드 오버로딩):

    • 같은 클래스 내에 같은 이름이지만 매개변수(수, 유형, 순서)가 다른 여러 메서드가 있는 경우 발생합니다.
    • 실행할 정확한 메서드는 컴파일 시간에 메서드 서명을 기반으로 결정됩니다.
  2. 런타임 다형성 (메서드 오버라이딩):

    • 하위 클래스가 이미 상위 클래스에 정의된 메서드에 대한 특정 구현을 제공하는 경우 발생합니다.
    • 실행할 메서드는 런타임에 결정되어, 일반적인 행동의 클래스에 대해 하나의 인터페이스를 사용할 수 있습니다.

핵심 개념

  1. 상속:

    • 다형성은 상속과 밀접한 관련이 있습니다. 하위 클래스는 상위 클래스의 메서드와 속성을 상속받지만, 메서드를 오버라이드할 수도 있습니다.
  2. 동적 메서드 디스패치:

    • 런타임 다형성에서, 오버라이드된 메서드에 대한 메서드 호출은 런타임에 해결되며, 이를 동적 메서드 디스패치라고 합니다.
  3. 인터페이스:

    • 많은 언어에서 다형성은 인터페이스나 추상 클래스를 통해 종종 달성되며, 서로 다른 클래스를 인터페이스 타입의 인스턴스로 취급할 수 있게 합니다.

장점

  1. 유연성과 재사용성:

    • 다형성을 통해 다양한 유형의 객체에 작동할 수 있는 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
  2. 유지보수성:

    • 새로운 클래스의 변경이나 추가가 기존 코드에 영향을 미치지 않도록 함으로써 코드의 유지보수성을 향상시킵니다.
  3. 추상화:

    • 인터페이스를 정의하고 다양한 구현을 가능하게 하는 것은 추상화의 한 형태입니다.

Dart 예제

다음은 Dart에서 런타임 다형성의 예시입니다:

class Animal {
  void speak() {
    print("동물이 소리를 냅니다");
  }
}

class Dog extends Animal {
  
  void speak() {
    print("개가 짖습니다");
  }
}

class Cat extends Animal {
  
  void speak() {
    print("고양이가 야옹합니다");
  }
}

void main() {
  List<Animal> animals = [Dog(), Cat(), Animal()];

  for (var animal in animals) {
    animal.speak();  // 동적 메서드 디스패치
  }
}

이 예시에서:

  • Animalspeak 메서드가 있는 상위 클래스입니다.
  • DogCatspeak 메서드를 오버라이드하는 하위 클래스입니다.
  • animals 리스트를 순회하며 speak를 호출할 때, 각 동물에 대한 특정 구현이 런타임에 호출되어 다형성을 보여줍니다.

결론

OOP에서 다형성은 객체를 상위 클래스 또는 인터페이스 타입의 인스턴스로 취급할 수 있게 해주어, 더 유연하고 유지보수하기 쉬운 코드를 가능하게 합니다. 이는 OOP가 복잡한 시스템을 더 효과적으로 모델링할 수 있게 하는 기본적인 개념입니다.

profile
공부하는 개발자

0개의 댓글