본문 바로가기
Delphi Tip/컴포넌트

델파이 컴포넌트(Component) 6편

by MonoSoft 2023. 7. 21.
728x90
반응형

델파이 컴포넌트(Component) 6편

728x90

 

 

 

 

프로퍼티(Property)

 

델파이는 참으로 재미있는 방법으로 클래스를 지원합니다.

그 중 하나가 바로 프로퍼티라는 녀석이죠.

 

OOP의 몇가지 대표적인 특징중에 캡슐화(정보은닉)이라는 것이 있죠?

 

OOP에서는 클래스 내부에서 다루는 데이터는 밖으로 드러나지 않아야 된다는 것이죠

내부에서 다루는 변수는 직접 조작할수가 없고,

함수를 통해서만이 값을 참조하고 바꿀수 있게 되어있습니다.

 

예를 들면 클래스 내부에서 쓰이는 변수중에 'fMyAge'라는 것이 있다구 합시다.

전형적인 C++언어에서는 fMyAge라는 녀석을 private안에 숨겨둘 것입니다.

 

그리고 다음과 같은 함수로 fMyAge를 조작할수 있도록 하겠죠.

 

C++에서의 변수접근법

i := GetMyAge();

SetMyAge( 18 );

 

델파이에 익숙한 우리들이 보기에는 좀 답답한 방법이죠..

 

델파이에서는 마찬가지로 fMyAge라는 변수를 private로 숨겨놓구도

 

다음과 같이 조작할수 있도록 해줍니다.

 

델파이에서의 변수접근법

i := MyAge;

MyAge := 18;

 

C++에서의 변수접근법에 비해서 엄청나게 간결하게 표현이 가능합니다.

 

물론 fMyAge를 public에 빼놓는다구 하더라도,

비슷하게 표현이 가능하지만 이런 경우는 어떻게 될까요?

 

MyAge := -12;

 

나이는 음수값이 될수 없겠죠?

이럴경우에도 별다른 처리없이 그대로 대입이 된다면

좀 문제가 생기게 될겁니다.

 

C++에서라면 SetMyAge라는 함수에서 처리를 하게 되죠?

 

(C++은 잘 모르므로 틀렸다면 지적바랍니다.)

void TMyClass :: SetMyAge( int age )

{

if age < 0 return; fMyAge = age;

}

 

그렇다면 우리의 델파이에서도 함수로 만들어서 처리를 하면 되죠..

 

procedure TMyClass.SetMyAge( age : integer );

begin

if age < 0 then exit;

fMyAge := age;

end;

 

이제 문제는 SetMyAge를 어떻게 불러 쓰느냐 하는 것입니다.

 

물론 C++과 같이 직접 함수를 불러서 사용할 수도 있겠지만

델파이에서는 좀 다른 특별한 방법을 이용합니다.

어떻게 이용할까요?

 

published

property MyAge : integer read GetMyAge write SetMyAge;

 

이런식으로 선언해 준다면, MyAge를 변수사용하듯이 사용하기만 하면 됩니다.

 

MyAge에 음수가 대입되었다든지 하는 등의 문제는

SetMyAge라는 함수에서 처리를 해 주면 되겠지요

 

MyAge를 통해서 값을 얻어오려구 한다면 GetMyAge가 불리게 되죠

또한 MyAge에 어떤값을 대입하려구 한다면 SetMyAge가 불리게 될 것입니다.

 

이런 일을 어떻게 구분할까요?

 

i := MyAge; <-

 

a) MyAge := 18; <- b) a)의 경우 'i'에다가 MyAge를 대입하는 경우이지요

따라서 MyAge의 값을 얻어오는 경우, 즉 GetMyAge가 쓰일 것입니다.

 

b)의 경우 MyAge에 '18'을 대입하는 경우이므로 SetMyAge가 쓰이게 될것입니다.

변수가 대입연산자( := )의 좌측에 있느냐?

우측에 있느냐에 따라서 다르게 행동하게 되겠죠?

참, 편리하게 되어 있죠?

 

C++의 경우처럼 내부변수를 처리할때 'Get__', 'Set__' 등의 함수를

불러주어야 한다면 꽤나 답답했을 겁니다.

 

(물론 C++빌더의 경우 델파이와의 호환성을 위해서 프로퍼티를 쓸수가 있죠..)

 

결국 우리가

MyButton.Caption := '울랄라';

 

라고 했을때 Caption이라는 변수를 직접 호출하는 것이 아니라,

Caption에 연결된 함수가 자동으로 호출된다는 것이죠..

 

물론 변수가 직접 연결될수도 있겠죠?

 

published

property MyAge : integer read fMyAge write SetMyAge;

 

MyAge의 값을 참조할 경우에는 값을 바로 읽어와도 상관이 없을 경우,

fMyAge를 read에 연결해 주어도 됩니다.

 

물론 다음과 같이 해도 되겠죠?

 

published

property MyAge : integer read fMyAge write fMyAge;

 

하지만 위의 경우에는 나이가 음수로 대입되는 등의 예외처리를 할수가 없으므로

좋은 방법이라 할수 없습니다.

 

그럼, read와 write에 연결되는 함수는 어떤 형태를 가져야 할까요?

이미 눈치채셨겠지만 간단한 규칙이 있습니다.

 

read의 경우 값을 읽어 오는 것이므로 function이어야 되겠죠?

 

물론 write의 경우에는 값을 대입하기만 하는 경우이므로 procedure로 선언되어야 합니다.

 

앞에서 예를 든 MyAge를 가지고 해 봅시다.

 

private

fMyAge : integer;

function GetMyAge : integer;

procedure SetMyAge( val : integer );

published property MyAge : integer read GetMyAge write SetMyAge;

 

우선 내부변수로 fMyAge라는 녀석을 만들어 봅시다.

 

integer형으로 선언하구요.

read에 연결될 함수는 값을 반환하고, write에서는 값을 대입하는 형태겠죠?

 

따라서 read에서는 integer형의 function이면 될테구..

write에서는 integer형의 매개변수를 취하는 procedure면 될겁니다.

 

형태(type)가 맞지 않으면 컴파일러가 에러를 내므로 주의하셔야 하구요..

 

7편계속....

728x90
반응형

댓글