인터페이스 정의(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)에서 이어져요.