본문 바로가기
Delphi/문법

델파이 인터페이스

by MonoSoft 2021. 5. 11.
728x90
반응형

델파이 인터페이스

 

 

인터페이스는 무엇인가?, 인터페이스 정의하기, 인터페이스를 구현하기.

 

델파이에서, "inteface"라는 키워드는 두개의 다른 뜻으로 쓰입니다.

 

OOP의 용어로는, 인터페이스를 '구현이 없는 클래스'라고 생각할 수 있습니다.

델파이 unit의 정의로는, interface section은 유닛의 코드중 public section을 선언하는 데 쓰입니다.

 

이글은 OOP입장에서의 인터페이스를 설명할 것입니다.

돌처럼 단단한 어플리케이션을 만들고 싶고,

코드를 유지보수하기 쉽고, 재사용 가능하고, 유연한 방법으로 만들고 싶다면,

델파이의 OOP적 품성이 당신의 가는 길의 70%를 도와줄 겁니다.

인터페이스들을 정의하고, 그 인터페이스들을 구현하는 것이 나머지 30%를 도와줄 겁니다.

 

< Abstract Classes로서의 Interfaces >

 

인터페이스를 'implementation이 제거되고, public이 아닌 것은 모두 빼버린 abstract class'라고 생각할 수 있습니다.

 

델파이에서의 abstract class는 인스턴스화 될 수 없는 클래스입니다.

- abstract라고 표시되 있다면, 객체를 만들 수 없습니다.

 

인터페이스를 선언하는 예를 보겠습니다.

 

type

IConfigChanged = interface

['{0D57624C-CDDE-458B-A36C-436AE465B477}']

procedure ApplyConfigChange;

end;

 

IConfigChanged는 하나의 인터페이스입니다. 하나의 인터페이스는 하나의 클래스와 매우 비슷하게 정의됩니다.

키워드 "class"대신에 "interface"를 씁니다.

 

"interface"키워드 바로 다음에 나오는 GUID 값은 컴파일러가 인터페이스를 식별하는 데에 쓰입니다.

새 GUID를 만들려면, 델파이 IDE상에서 Ctrl+Shift+G를 누르기만 하면 됩니다.

여러분이 정의하는 인터페이스 각각은 각자만의 GUID를 필요로 합니다.

 

OOP에서의 인터페이스는, 실제 클래스의 abstraction-template을 정의합니다.

구현은 실제 클래스가 합니다.

- 인터페이스에 의해 정의된 메소드를 구현합니다.

 

인터페이스는 실제로 아무것도 하지 않습니다.

다른 implementing class, class, interface와 상호작용을 하겠다는 표시일뿐입니다.

'인터페이스를 구현하는 클래스'에서 메소드(function, procedure, property Get/Set 메소드)들이 구현됩니다.

인터페이스 정의부에는 ( private, public, published등등의) scope section이 없습니다.

모두 public입니다.

인터페이스는

function,

procedure(이것이 결국은 '인터페이스 구현 클래스'의 메소드가 됩니다.),

property를 정의할 수 있습니다.

인터페이스가 property를 정의할 때에는 꼭 get/get 메소드를 정의해 주어야 합니다.

- 인터페이스는 변수를 정의할 수 없습니다.

 

클래스처럼, 인터페이스도 다른 인터페이스를 상속받을 수 있습니다.

 

type

IConfigChangedMore = interface(IConfigChanged)

procedure ApplyMoreChanges;

end;

 

< 인터페이스는 COM과만 엮이는 것이 아닙니다. >

 

대부분의 델파이 개발자는 인터페이스에 대해 생각할 때, COM 프로그래밍을 생각합니다.

그렇지만, 인터페이스는 그저 OOP의 한 측면입니다. COM에 묶여 있는 것이 아닙니다.

 

델파이에서 COM을 건드리지 않고도 , 인터페이스를 정의하고 구현할 수 있습니다.

 

< 인터페이스 구현하기 >

인터페이스를 구현하려면, 인터페이스의 이름을 해당 클래스문에 첨가해 주어야 합니다.

 

type

TMainForm = class(TForm, IConfigChanged)

public

procedure ApplyConfigChange;

end;

 

위의 코드에서, MainForm이라는 이름의 델파이 폼은 IConfigChanged 인터페이스를 구현합니다.

주의: 클래스가 인터페이스를 구현할 때에는 인터페이스의 모든 메소드들과 프로퍼티들을 구현해야합니다.

만약 메소드를 하나 빼 먹으면(위의 예라면, ApplyConfigChange를 빼먹으면),

컴파일 타임 에러, "E2003 Undeclared identifier: 'ApplyConfigChange'"가 뜰 겁니다.

주의: GUID값 없이 인터페이스를 명시하면

"E2086 Type 'IConfigChanged' 에러 납니다.

 

< 언제 인터페이스를 씁니까? 마지막으로 실생활에서의 예. :) >

제게는 MDI 어플리케이션이 하나 있습니다. 많은 폼을 갖고 있고, 한번에 펼쳐보여지기도 합니다.

유저가 설정을 바꾸면, 거의 모든 폼이 표시화면을 업데이트해야 합니다.

: 어떤 버튼들은 숨기거나 보여야 합니다, label.caption들도 업데이트해야 합니다. 등등

 

저는 어플리케이션의 설정이 바뀌었다는 것을 모든 열린 폼들에게 알려줄 간단한 방법이 필요합니다.

 

이상적인 도구는 인터페이스입니다.

 

설정의 변화를 알아야 하는 모든 폼들은 IConfigChanged를 구현할 생각입니다.

 

설정화면은 modal이기 때문에, 설정화면을 닫으면,

다음 코드에 의해서,

IConfigChanged를 구현하고 있는 모든 폼들은 알게 되고, ApplyChange가 호출됩니다.

 

procedure DoConfigChange() ;

var

cnt : integer;

icc : IConfigChanged;

begin

for cnt := 0 to -1 + Screen.FormCount do

begin

if Supports(Screen.Forms[cnt], IConfigChanged, icc) then

icc.ApplyConfigChange;

end;

end;

 

Support함수(Sysutils.pas에 있는)는,

주어진 객체나 인터페이스가 특정 인터페이스를 지원하는지 여부를 알려줍니다.

 

위의 코드는, (TScreen의) Screen.Forms collection을 돕니다.

- 현재 화면에 떠 있는 모든 폼들을 살핍니다.

만약 Screen.Forms[cnt]가 인터페이스를 지원하면, Support함수는 마지막 인자로 인터페이스를 반환하고, true를 리턴합니다.

 

그러므로 폼이 ICongigChanged를 구현하면,

icc 변수를

폼에 의해서 구현된 인터페이스 메소드를 호출하는 데에

쓸 수 있습니다.

 

물론, 각각의 폼은 자신만의 방식으로 ApplyConfigChange를 구현할 수 있습니다.

 

< IUnknown, IInterface, TInterfacedObject, QuerryInterface, _AddRef, _Release >

 

힘든 힘을 간단하게 해 보겠습니다. :)

 

델파이에 선언된 어떤 클래스든 조상이 있습니다. TObject는 모둔 객체와 컴포넌트의 최상위 조상입니다.

 

위의 개념은 인터페이스에도 적용이 됩니다. IInterface는 모든 인터페이스의 조상입니다.

IInterface는 3개의 메소드를 정의합니다.: QueryInterface, _AddRef, _Release.

 

IConfigChanged 역시 3개의 메소드를 갖고 있다는 뜻입니다. 하지만 우리는 구현하지 않았습니다.

이유는 이렇습니다.

 

TForm은 TComponent로부터 상속받습니다.

TComponent는 이미 여러분을 위해서 IInterface를 구현했습니다!

 

여러분이 TObject에서 상속 받은 클래스로 인터페이스를 구현하고 싶을 때에는,

대신에, TInterfacedObject에서 상속받는 것을 잊지 마십시오.

IInterface를 구현하고 있는 TObject가 TInterfacedObject이기 때문입니다.

 

예를 들면,

TMyClass = class(TInterfacedObject, IConfigChanged)

procedure ApplyConfigChange;

end;

 

마지막으로 좀 더 정리하자면,

IUnknown = IInterface.

IUnknown is for COM.

728x90
반응형

'Delphi > 문법' 카테고리의 다른 글

델파이 제네릭(Generic) 용어  (0) 2021.05.12
델파이 제네릭(Generic) 개요  (0) 2021.05.12
델파이 다중 동적 배열  (0) 2021.05.11
델파이 TThread 사용 길잡이  (0) 2021.05.10
델파이 예외처리  (0) 2021.05.06

댓글