중첩 타입, 상수, 변수(Nested Types, Constants and Variables)

중첩 타입, 상수, 변수(Nested Types, Constants and Variables)

클래스 정의 안에 type 절과 const 절, var 절을 넣을 수 있어요. 이렇게 클래스에 묶인 타입·상수·변수는 밖에서 어떻게 보이는지가 살짝 까다로워요. 특히 접근 지정자(public/private)가 어떤 영향을 주는지가 핵심이에요.

출처: Nested types, constants and variables

본문

클래스 정의는 type 절과 const 절, var 절을 포함할 수 있어요. type 절과 const 절은 유닛이나 메서드/함수/프로시저 구현부에서 쓰는 일반 type 절과 똑같이 동작해요. var 절은 클래스의 일반 필드처럼 동작하는데, 단 class var 절에 있으면 유닛 레벨에서 정의된 것처럼 클래스의 네임스페이스 안에 존재한다고 간주돼요(6.3 절 참고).

여기서 접근 지정자가 역할을 해요. private/protected(strict 여부와 무관하게) 상수·타입·변수는 그 가시성이 허락하는 범위에서만 쓸 수 있어요. public 타입은 클래스 밖에서도 전체 이름으로 사용할 수 있어요.

type
   TA = Class(TObject)
   Public
     Type TEnum = (a,b,c);
     Class Function DoSomething : TEnum;
   end;

 Class Function TA.DoSomething : TEnum;

 begin
   Result:=a;
 end;

 var
   E : TA.TEnum;

 begin
   E:=TA.DoSomething;
 end.

반면 아래처럼 타입을 Strict Private으로 선언하면, public 메서드가 그 타입을 반환해도 밖에서는 쓸 수 없어요.

type
   TA = Class(TObject)
   Strict Private
     Type TEnum = (a,b,c);
   Public
     Class Function DoSomething : TEnum;
   end;

 Class Function TA.DoSomething : TEnum;

 begin
   Result:=a;
 end;

 var
   E : TA.TEnum;

 begin
   E:=TA.DoSomething;
 end.

이 코드는 컴파일되지 않고 에러가 나요.

tt.pp(20,10) Error: identifier idents no member "TEnum"

쓰기 가능한 상수(writeable constant)에 대해서는 클래스 변수와 같은 규칙이 적용돼요. 범위와 파생 클래스에서의 오버라이드 관점에서 볼 때 그래요. 아래 두 경우를 비교해 볼게요.

{$mode delphi}{$J+}
 type
   TA = class // base type
     const CODE: integer = 99;
   end;
   TB = class(TA);
   TC = class(TA);

 begin
   TA.Code:=0;
   TB.Code:=1;
   TC.Code:=2;
   Writeln(Ta.Code:2,Tb.Code:2,Tc.code:2);
 end.

이 코드는 아래처럼 출력해요.

2 2 2

왜냐하면 TA, TB, TC가 모두 같은 상수 CODE를 공유하기 때문이에요. 그런데 파생 클래스에서 각자 자기만의 CODE를 다시 선언하면 상황이 달라져요.

{$mode delphi}{$J+}
 type
   TA = class // base type
     const CODE: integer = -99;
   end;
   TB = class(TA)
     const code : integer = -98;
   end;
   TC = class(TA)
     Const code : integer = -97;
   end;

 begin
   TA.Code:=0;
   TB.Code:=1;
   TC.Code:=2;
   Writeln(Ta.Code:2,Tb.Code:2,Tc.code:2);
 end.

이번에는 아래처럼 출력돼요.

0 1 2

즉 각 클래스가 자기만의 CODE를 따로 갖게 되는 거예요.

더 알아보기

  • class var 클래스 변수의 동작은 6.3 절(클래스)에서 자세히 다뤄요.
  • 클래스 프로퍼티와의 연결점은 6.8 절(클래스 프로퍼티)에서 확인할 수 있어요.
  • 접근 지정자(public/private/protected)의 일반 규칙은 클래스 선언 부분을 참고해요.