Menu
Coddy logo textTech

call() 메서드

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

Dart에는 객체를 마치 함수처럼 사용할 수 있게 해주는 call()이라는 특별한 메서드가 있습니다. 클래스가 call() 메서드를 정의하면, 함수 호출 구문을 사용하여 해당 클래스의 인스턴스를 호출할 수 있습니다.

class Multiplier {
  int factor;
  
  Multiplier(this.factor);
  
  int call(int value) {
    return value * factor;
  }
}

void main() {
  var double = Multiplier(2);
  var triple = Multiplier(3);
  
  print(double(5));  // 10 - 객체를 함수처럼 호출함
  print(triple(5));  // 15
}

double.call(5)라고 쓰는 대신, 간단히 double(5)라고 쓸 수 있습니다. Dart는 객체에 괄호를 사용할 때 call() 메서드를 자동으로 호출합니다.

call() 메서드는 일반적인 메서드와 마찬가지로 어떤 매개변수도 받을 수 있고 어떤 타입도 반환할 수 있습니다:

class Greeter {
  String prefix;
  
  Greeter(this.prefix);
  
  String call(String name, {String punctuation = '!'}) {
    return '$prefix, $name$punctuation';
  }
}

void main() {
  var hello = Greeter('Hello');
  print(hello('Alice'));  // Hello, Alice!
  print(hello('Bob', punctuation: '?'));  // Hello, Bob?
}

이 패턴은 함수처럼 동작하면서도 상태나 설정을 유지해야 하는 객체가 필요할 때 유용합니다. 호출 사이에 설정을 기억해야 하는 재사용 가능한 연산, 유효성 검사기(validator) 또는 포맷터(formatter)를 만드는 데 흔히 사용됩니다.

challenge icon

챌린지

쉬움

포맷터 객체를 함수처럼 직접 호출할 수 있는 텍스트 포맷터 시스템을 만들어 봅시다! 설정 값을 유지하면서 다양한 방식으로 텍스트를 변환하는 호출 가능한 클래스(callable classes)를 만들게 됩니다.

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

  • formatters.dart: 문자열을 변환하는 두 개의 호출 가능한 클래스를 생성합니다:
    • 설정 가능한 접두사(prefix)와 접미사(suffix)로 텍스트를 감싸는 Wrapper 클래스. 이 클래스는 prefixsuffix 문자열을 저장해야 하며, call() 메서드는 String text를 인자로 받아 접두사와 접미사로 감싸진 텍스트를 반환해야 합니다.
    • 텍스트를 설정된 횟수만큼 반복하는 Repeater 클래스. 이 클래스는 times 정수를 저장해야 하며, call() 메서드는 String text를 인자로 받아 해당 횟수만큼 반복되고 공백으로 구분된 텍스트를 반환해야 합니다.
  • main.dart: 포맷터를 임포트하고 이 객체들이 함수처럼 어떻게 사용되는지 보여줍니다:
    • 접두사 '['와 접미사 ']'를 가진 Wrapper를 생성합니다.
    • 접두사 '***'와 접미사 '***'를 가진 또 다른 Wrapper를 생성합니다.
    • 반복 횟수가 3으로 설정된 Repeater를 생성합니다.
    • 첫 번째 래퍼를 'Hello'와 함께 호출하고 결과를 출력합니다.
    • 두 번째 래퍼를 'Important'와 함께 호출하고 결과를 출력합니다.
    • 리피터를 'Go'와 함께 호출하고 결과를 출력합니다.
    • 첫 번째 래퍼의 결과('Nested'를 넣은 결과)를 두 번째 래퍼에 전달하여 체이닝을 보여주고, 결과를 출력합니다.

일반 함수와 마찬가지로 괄호를 사용하여 포맷터 객체를 직접 호출할 수 있는 점에 주목하세요. call() 메서드가 이를 가능하게 하며, 각 객체는 사용 시점 사이에 자신의 설정 값을 기억합니다!

예상 출력:

[Hello]
***Important***
Go Go Go
***[Nested]***

치트 시트

call() 메서드를 사용하면 객체를 함수처럼 사용할 수 있습니다. 클래스가 call() 메서드를 정의하면, 함수 호출 구문을 사용하여 해당 클래스의 인스턴스를 호출할 수 있습니다.

class Multiplier {
  int factor;
  
  Multiplier(this.factor);
  
  int call(int value) {
    return value * factor;
  }
}

void main() {
  var double = Multiplier(2);
  print(double(5));  // 10 - 객체를 함수처럼 호출함
}

double.call(5)라고 쓰는 대신, 간단히 double(5)라고 쓸 수 있습니다. 객체에 괄호를 사용하면 Dart가 자동으로 call() 메서드를 호출합니다.

call() 메서드는 어떠한 매개변수도 받을 수 있으며 어떠한 타입도 반환할 수 있습니다:

class Greeter {
  String prefix;
  
  Greeter(this.prefix);
  
  String call(String name, {String punctuation = '!'}) {
    return '$prefix, $name$punctuation';
  }
}

void main() {
  var hello = Greeter('Hello');
  print(hello('Alice'));  // Hello, Alice!
  print(hello('Bob', punctuation: '?'));  // Hello, Bob?
}

이 패턴은 함수처럼 동작하면서도 호출 간에 상태나 설정을 유지하는 객체를 만드는 데 유용합니다.

직접 해보기

import 'formatters.dart';

void main() {
  // TODO: 접두사 '['와 접미사 ']'를 가진 Wrapper를 생성하세요
  
  // TODO: 접두사 '***'와 접미사 '***'를 가진 또 다른 Wrapper를 생성하세요
  
  // TODO: 횟수가 3으로 설정된 Repeater를 생성하세요
  
  // TODO: 첫 번째 wrapper를 'Hello'와 함께 호출하고 결과를 출력하세요
  
  // TODO: 두 번째 wrapper를 'Important'와 함께 호출하고 결과를 출력하세요
  
  // TODO: repeater를 'Go'와 함께 호출하고 결과를 출력하세요
  
  // TODO: 첫 번째 wrapper의 결과('Nested' 포함)를 두 번째 wrapper에 전달하여
  // 체이닝을 시연하고, 그 결과를 출력하세요
}
quiz icon실력 점검

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

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