클래스 연산자
클래스 연산자
클래스 연산자는 앞에서 본 연산자들과 조금 달라요. 클래스를 돌려주는 클래스 표현식에서만 사용할 수 있거든요. 클래스 연산자는 표 12.8에 보이는 것처럼 딱 두 개예요.
출처: 문서
본문
표 12.8: 클래스 연산자
| 연산자 | 동작 |
|---|---|
is |
클래스 타입 검사 |
as |
조건부 타입 변환(typecast) |
is 연산자를 포함한 표현식은 불리언 타입 결과를 내요. is 연산자는 클래스 참조(class reference)나 클래스 인스턴스에서만 사용할 수 있어요. 사용법은 다음과 같아요.
Object is Class
이 표현식은 다음 코드와 완전히 동일해요.
Object.InheritsFrom(Class)
Object가 Nil이면 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;
as와 is 연산자는 인터페이스(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으로 얻은 인터페이스에서는 동작하지 않아요.