인터페이스 정의(Interface Definition)

인터페이스 정의(Interface Definition)

여러 개의 부모 클래스를 가질 수 있는 다중 상속은 언어에 따라 지원 방식이 달라요. Free Pascal은 그 대안으로 **인터페이스(interface)**를 지원해요. 인터페이스는 메서드와 프로퍼티의 이름만 정해 둔 '약속'이라서, 한 클래스가 여러 인터페이스를 구현해도 충돌 없이 유연하게 쓸 수 있어요.

출처: Definition

본문

FPC는 1.1 버전부터 인터페이스를 지원해요. 인터페이스는 C++처럼 클래스가 여러 부모 클래스를 가질 수 있는 다중 상속의 대안이에요. 인터페이스는 기본적으로 이름 붙여진 메서드·프로퍼티 집합이에요. 인터페이스를 구현하는 클래스는 인터페이스 정의에 열거된 모든 메서드를 제공해요. 인터페이스의 일부만 구현하는 건 불가능해요. 전부 아니면 전무(all or nothing)예요.

인터페이스도 클래스처럼 계층 구조를 만들 수 있어요. 다른 인터페이스를 상속하는 인터페이스 정의는 부모 인터페이스의 모든 메서드에 더해, 자기 자신이 명시적으로 이름 붙인 메서드까지 모두 포함해요. 그래서 어떤 인터페이스를 구현하는 클래스는 그 인터페이스의 모든 멤버와 부모 인터페이스(들)의 메서드까지 모두 구현해야 해요.

인터페이스는 GUID로 고유하게 식별할 수 있어요. GUID는 Globally Unique Identifier의 약자로, 128비트 정수이며 항상 고유하다고 보장되는 값이에요(이론상으로는 그렇죠). 특히 Windows 시스템에서는 COM을 쓸 때 인터페이스의 GUID를 사용할 수 있고 또 사용해야 해요.

인터페이스 정의의 형태는 다음과 같아요.

Interface type

정의와 함께 반드시 기억해야 할 점들이 있어요.

  • 인터페이스는 DELPHI 모드나 OBJFPC 모드에서만 사용할 수 있어요.
  • 가시성 지정자가 없어요. 모든 멤버는 public이에요(사실 private/protected로 만들 이유가 별로 없죠).
  • 인터페이스에 선언된 프로퍼티는 read/write 지정자로 메서드만 가질 수 있어요.
  • 생성자나 파괴자가 없어요. 인터페이스의 인스턴스를 직접 만들 수 없고, 대신 인터페이스를 구현하는 클래스의 인스턴스를 만들어야 해요.
  • 메서드 정의에는 호출 규약(calling convention) 지정자만 올 수 있어요. virtual, abstract, dynamic 같은 수식어는 인터페이스 정의에 올 수 없고, 따라서 override도 불가능해요.

인터페이스의 예를 볼게요.

IUnknown = interface ['{00000000-0000-0000-C000-000000000046}']
   function QueryInterface(const iid : tguid;out obj) : longint;
   function _AddRef : longint;
   function _Release : longint;
 end;
 IInterface = IUnknown;

 IMyInterface = Interface
   Function MyFunc : Integer;
   Function MySecondFunc : Integer;
 end;

위에서 볼 수 있듯이, 인터페이스를 식별하는 GUID는 선택 사항이에요.

더 알아보기

  • 인터페이스를 GUID로 식별하는 방법은 다음 절에서 자세히 다뤄요.
  • 클래스가 인터페이스를 구현하는 방법은 7.3 절을 참고해요.
  • 인터페이스의 계층 구조는 7.4 절(인터페이스 상속)에서 확인할 수 있어요.
  • IUnknown 인터페이스의 역할은 7.6 절(인터페이스와 COM)에서 이어져요.