Menu
Coddy logo textTech

인터페이스의 개념

Coddy C 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 40번째.

지금까지 우리의 구조체는 데이터와 동작을 함께 포함했습니다. 예를 들어 이름과 function 포인터를 나란히 포함하는 식입니다. 하지만 구조체가 오직 function 포인터만 포함한다면 어떨까요? 이것은 강력한 무언가를 만들어 냅니다. 바로 interface입니다.

interface는 어떤 연산을 사용할 수 있는지 정의하지만, 그것이 어떻게 작동하는지는 지정하지 않습니다. 이는 "이 interface를 구현하는 모든 객체는 이러한 functions를 제공해야 한다"라고 말하는 계약입니다.

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

ILogger 구조체에는 function pointer만 들어 있습니다. 자체 데이터는 없습니다. 순전히 동작을 설명합니다. "I" 접두사는 이것이 인터페이스임을 나타내는 일반적인 관례입니다.

ILogger를 받는 모든 코드는 로그 메시지가 어디로 전달되는지 신경 쓰지 않습니다. 콘솔에 출력하거나, 파일에 쓰거나, 네트워크를 통해 데이터를 보낼 수도 있습니다. 호출자는 log를 호출할 수 있다는 것만 알면 됩니다.

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // 우리는 그것이 어떻게 로그하는지 모른다
}

이러한 분리가 다형성의 본질입니다. process 함수는 어떤 logger 구현과도 함께 작동합니다. 함수의 코드를 변경하지 않고 동작을 바꿀 수 있습니다. 다음 레슨에서는 이 interface 계약을 충족하는 구체적인 구현을 만들게 됩니다.

challenge icon

챌린지

쉬움

ICalculator interface를 만들어 봅시다. 이는 function 포인터만 포함하는 struct로, 각 calculator가 지원해야 하는 operation을 작동 방식은 지정하지 않고 정의합니다.

코드를 구성하기 위해 두 개의 파일을 만듭니다.

  • calculator.h: 여기에서 interface를 Define합니다. 두 개의 int parameters를 받고 int를 반환하는 BinaryOp function 포인터 type을 Create합니다. 그런 다음 두 개의 function 포인터만 포함하는 ICalculator struct를 Define합니다. 하나는 operate(type은 BinaryOp)이고, 다른 하나는 parameters를 받지 않고 아무것도 반환하지 않는 function 포인터인 describe입니다. 이 struct는 순수한 interface입니다. data는 보유하지 않고 behavior만 보유합니다.
  • main.c: header를 포함하고 interface를 충족할 수 있는 구체적인 functions를 Implement합니다.
    • add: 두 integers의 합을 반환합니다.
    • multiply: 두 integers의 product를 반환합니다.
    • describe_add: Addition을 출력합니다.
    • describe_multiply: Multiplication을 출력합니다.
    그런 다음 ICalculator instance를 Create하고, input에 따라 연결한 후, 이를 사용하여 계산을 수행합니다.

프로그램은 세 가지 input을 받습니다. 두 개의 integersoperation code입니다(덧셈은 1, 곱셈은 2).

operation code에 따라 적절한 두 functions로 ICalculator를 연결합니다. 그런 다음 interface를 통해 describe를 Call하여 operation name을 출력하고, 이어서 operate를 Call하여 result를 계산하고 출력합니다.

input이 5, 3, 1일 때의 example output:

Addition
8

input이 4, 7, 2일 때의 example output:

Multiplication
28

핵심 insight는 ICalculator struct가 contract를 Define한다는 것입니다. 이를 사용하는 어떤 code든 어떤 specific functions가 연결되어 있는지는 know하지 못하더라도 describeoperate를 Call할 수 있다는 것을 know합니다. header file에서 include guards를 사용하는 것을 잊지 마세요.

직접 해보기

#include <stdio.h>
#include "calculator.h"

// TODO: add 함수를 구현하세요
// 두 정수의 합을 반환합니다


// TODO: multiply 함수를 구현하세요
// 두 정수의 곱을 반환합니다


// TODO: describe_add 함수를 구현하세요
// "Addition"을 출력합니다


// TODO: describe_multiply 함수를 구현하세요
// Prints "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: ICalculator 인스턴스를 생성하세요
    
    
    // TODO: op_code에 따라 (1은 add, 2는 multiply),
    // 적절한 함수로 계산기를 연결하세요
    
    
    // TODO: 인터페이스를 통해 describe를 호출하세요
    
    
    // TODO: 인터페이스를 통해 operate를 호출하고 결과를 출력하세요
    
    
    return 0;
}
quiz icon실력 점검

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

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

직접 연습해 보세요: 온라인 C 컴파일러