클래스 연산자

클래스 연산자

클래스 연산자는 앞에서 본 연산자들과 조금 달라요. 클래스를 돌려주는 클래스 표현식에서만 사용할 수 있거든요. 클래스 연산자는 표 12.8에 보이는 것처럼 딱 두 개예요.

출처: 문서

본문

표 12.8: 클래스 연산자

연산자 동작
is 클래스 타입 검사
as 조건부 타입 변환(typecast)

is 연산자를 포함한 표현식은 불리언 타입 결과를 내요. is 연산자는 클래스 참조(class reference)나 클래스 인스턴스에서만 사용할 수 있어요. 사용법은 다음과 같아요.

Object is Class

이 표현식은 다음 코드와 완전히 동일해요.

Object.InheritsFrom(Class)

ObjectNil이면 False를 돌려줘요.

예시를 볼게요.

Var
   A : TObject;
   B : TClass;
 begin
   if A is TComponent then ;
   If A is B then;
 end;

as 연산자는 조건부 타입 변환을 수행해요. 결과는 클래스의 타입을 가진 표현식이에요.

Object as Class

이는 다음 코드와 동일해요.

If Object=Nil then
   Result:=Nil
 else if Object is Class then
   Result:=Class(Object)
 else
   Raise Exception.Create(SErrInvalidTypeCast);

여기서 주의할 점이 하나 있어요. 객체가 nil이면 as 연산자는 예외를 발생시키지 않아요.

as 연산자 사용 예시를 볼게요.

Var
   C : TComponent;
   O : TObject;
 begin
   (C as TEdit).Text:='Some text';
   C:=O as TComponent;
 end;

asis 연산자는 인터페이스(COM과 CORBA 모두)에서도 동작해요. 인터페이스가 다른 인터페이스도 구현하는지 검사하는 데 쓸 수 있어요. 다음 예시를 볼게요.

{$mode objfpc}
 uses
   SysUtils;
 type
   IMyInterface1 = interface
     ['{DD70E7BB-51E8-45C3-8CE8-5F5188E19255}']
     procedure Bar;
   end;
   IMyInterface2 = interface
     ['{7E5B86C4-4BC5-40E6-A0DF-D27DBF77BCA0}']
     procedure Foo;
   end;
   TMyObject = class(TInterfacedObject, IMyInterface1, IMyInterface2)
     procedure Bar;
     procedure Foo;
   end;
 procedure TMyObject.Bar;
 begin
 end;
 procedure TMyObject.Foo;
 begin
 end;
 var
   i: IMyInterface1;
 begin
   i := TMyObject.Create;
   i.Bar;
   Writeln(BoolToStr(i is IMyInterface2, True)); // prints true
   Writeln(BoolToStr(i is IDispatch, True)); // prints false
   (i as IMyInterface2).Foo;
 end.

추가로 is 연산자는 클래스가 인터페이스를 구현하는지 검사하는 데, as 연산자는 인터페이스를 다시 클래스로 타입 변환하는 데 사용할 수 있어요.

{$mode objfpc}
 var
   i: IMyInterface;
 begin
   i := TMyObject.Create;
   Writeln(BoolToStr(i is TMyObject,True)); // prints true
   Writeln(BoolToStr(i is TObject,True)); // prints true
   Writeln(BoolToStr(i is TAggregatedObject,True)); // prints false
   (i as TMyObject).Foo;
 end.

여기서 한 가지 제약이 있어요. 인터페이스가 COM 인터페이스여야 하는 건 맞지만, 클래스로의 역타입 변환이 동작하려면 그 인터페이스가 Object Pascal 클래스에서 비롯된 경우여야 해요. 시스템에서 COM으로 얻은 인터페이스에서는 동작하지 않아요.

더 알아보기