유형 검사

유형 검사는 컴파일 타임이나 런타임에 수행할 수 있습니다. C++ 및 Java와 같이 정적으로 유형이 지정되는 언어는 컴파일 타임에 유형 검사를 수행합니다. Smalltalk 및 Python과 같이 동적으로 유형이 지정되는 언어는 런타임에 유형 검사를 처리합니다. 동적으로 유형이 지정되는 언어인 ActionScript 3.0의 경우 런타임에 유형 검사를 수행하지만 Strict 모드라는 특수 컴파일러 모드에서의 컴파일 타임 유형 검사도 지원합니다. Strict 모드에서는 컴파일 타임과 런타임에 모두 유형 검사가 수행되지만, Standard 모드에서는 런타임에만 유형 검사가 수행됩니다.

동적으로 유형이 지정되는 언어를 사용하면 코드를 구성할 때 상당한 융통성을 누릴 수 있지만 런타임에 유형 오류가 출력되는 것을 감수해야 합니다. 정적으로 유형이 지정되는 언어를 사용하면 컴파일 타임에 유형 오류를 확인할 수 있지만 컴파일러에게 유형 정보를 제공해야 하는 부담을 지게 됩니다.

세부 목차

컴파일 타임 유형 검사
런타임 유형 검사
is 연산자
as 연산자

컴파일 타임 유형 검사

프로젝트 규모가 커지면 일반적으로 데이터 유형 유연성보다 유형 오류를 가능한 빨리 포착하는 것이 중요해지므로 대형 프로젝트에서는 컴파일 타임 유형 검사가 자주 사용됩니다. 이러한 이유 때문에 Adobe Flash CS3 Professional 및 Adobe Flex Builder 2의 ActionScript 컴파일러가 Strict 모드에서 실행되도록 기본 설정되어 있습니다.

컴파일 타임 유형 검사를 제공하려면 컴파일러에서 코드의 변수 또는 표현식에 대한 데이터 유형 정보를 알고 있어야 합니다. 변수의 데이터 유형을 명시적으로 선언하려면 변수 이름에 콜론 연산자(:)를 추가하고 그 뒤에 데이터 유형을 접미어로 추가합니다. 데이터 유형을 매개 변수와 연결하려면 콜론 연산자와 데이터 유형을 차례로 사용합니다. 예를 들어 다음 코드에서는 xParam 매개 변수에 데이터 유형 정보를 추가하고 명시적 데이터 유형을 사용하여 myParam 변수를 선언합니다.

function runtimeTest(xParam:String)
{
    trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);

Strict 모드의 ActionScript 컴파일러에서는 컴파일러 오류에 따라 유형 불일치를 보고합니다. 예를 들어, 다음 코드에서는 Object 유형의 xParam 함수 매개 변수를 선언하지만 이후 해당 매개 변수에 String 및 Number 유형 값을 지정하려고 합니다. 이로 인해 Strict 모드에서 컴파일러 오류가 발생합니다.

function dynamicTest(xParam:Object)
{
    if (xParam is String)
    {
        var myStr:String = xParam; // Strict 모드에서 컴파일러 오류가 발생합니다.
        trace("String: " + myStr);
    }
    else if (xParam is Number)
    {
        var myNum:Number = xParam; // Strict 모드에서 컴파일러 오류가 발생합니다.
        trace("Number: " + myNum);
    }
}

그러나 Strict 모드에서도 대입문의 우변을 유형이 지정되지 않은 상태로 두면 컴파일 타임 유형 검사에서 해당 대입문을 제외할 수 있습니다. 유형 약어를 생략하거나 특수 별표(*) 유형 약어를 사용하여 유형이 지정되지 않은 변수 또는 표현식을 표시할 수 있습니다. 예를 들어, 이전 예제를 수정하여 xParam 매개 변수의 유형 약어를 생략하면 Strict 모드에서 코드가 컴파일됩니다.

function dynamicTest(xParam)
{
    if (xParam is String)
    {
        var myStr:String = xParam;
        trace("String: " + myStr);
    }
    else if (xParam is Number)
    {
        var myNum:Number = xParam;
        trace("Number: " + myNum);
    }
}
dynamicTest(100)            
dynamicTest("one hundred");

런타임 유형 검사

ActionScript 3.0에서는 Strict 모드 또는 Standard 모드 중 어느 모드에서 컴파일했는지와 관계없이 런타임 유형 검사가 수행됩니다. 배열 인수가 필요한 함수에 값 3이 전달되는 경우를 생각해 봅시다. 값 3이 Array 데이터 유형과 호환되지 않으므로 Strict 모드의 컴파일러에서 오류가 발생합니다. Strict 모드를 사용하지 않고 Standard 모드에서 실행하는 경우 컴파일러에서는 유형 불일치에 대한 오류가 발생하지 않지만 Flash Player에서 런타임 유형 검사를 수행하면 런타임 오류가 발생합니다.

다음 예제에서는 필요한 Array 인수 대신 값 3이 전달된 typeTest() 함수를 보여 줍니다. 값 3이 매개 변수의 선언된 데이터 유형(Array)의 멤버가 아니기 때문에 Standard 모드에서 런타임 오류가 발생합니다.

function typeTest(xParam:Array)
{
    trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum); 
// Standard 모드에서 런타임 오류가 발생합니다.

Strict 모드에서 작업하는 경우에도 런타임 유형 오류가 발생할 수 있습니다. Strict 모드에서 유형이 지정되지 않은 변수를 사용하면 컴파일 타임 유형 검사에서 해당 변수가 제외되므로 런타임에 유형 오류가 발생할 수도 있습니다. 유형이 지정되지 않은 변수를 사용하는 경우 유형 검사는 취소되지 않고 런타임까지 연기됩니다. 예를 들어 이전 예제의 myNum 변수에 선언된 데이터 유형이 없는 경우 컴파일러에서는 유형 불일치를 감지할 수 없지만 Flash Player에서는 런타임 오류가 발생합니다. 이는 Flash Player에서 대입문의 결과 값인 3으로 설정된 myNum의 런타임 값을 Array 데이터 유형으로 설정된 xParam의 유형과 비교하기 때문입니다.

function typeTest(xParam:Array)
{
    trace(xParam);
}
var myNum = 3;
typeTest(myNum); 
// ActionScript 3.0에서 런타임 오류가 발생합니다.

또한 런타임 유형 검사의 경우 컴파일 타임 검사에 비해 상속의 사용을 덜 엄격하게 검사합니다. Standard 모드에서 유형 검사를 런타임으로 연기하면 하위 클래스를 업캐스팅한 경우에도 하위 클래스의 속성을 참조할 수 있습니다. 기본 클래스를 사용하여 클래스 인스턴스의 유형을 선언하고, 하위 클래스를 사용하여 클래스 인스턴스를 인스턴스화하면 업캐스팅이 일어납니다. 예를 들어 확장할 수 있는 ClassBase 클래스를 만들 수 있습니다. final 특성이 있는 클래스는 확장할 수 없습니다.

class ClassBase
{
}

이어서 다음과 같이 someString 속성 하나가 있는 ClassExtender라는 ClassBase의 하위 클래스를 만들 수 있습니다.

class ClassExtender extends ClassBase
{
    var someString:String;
}

두 클래스를 사용하면 ClassBase 데이터 유형으로 선언되고 ClassExtender 생성자로 인스턴스화되는 클래스 인스턴스를 만들 수 있습니다. 기본 클래스에는 하위 클래스에 없는 속성 또는 메서드가 포함되어 있지 않기 때문에 업캐스팅은 안전한 작업으로 간주됩니다.

var myClass:ClassBase = new ClassExtender();

그러나 하위 클래스에는 기본 클래스에 없는 속성 또는 메서드가 포함되어 있습니다. 예를 들어, ClassExtender 클래스에는 ClassBase 클래스에 없는 someString 속성이 포함되어 있습니다. ActionScript 3.0 Standard 모드에서 다음 예제와 같이 컴파일 타임 오류를 생성하지 않고 myClass 인스턴스를 사용하여 이 속성을 참조할 수 있습니다.

var myClass:ClassBase = new ClassExtender();
myClass.someString = "hello";
// ActionScript 3.0 Standard 모드에서 오류가 발생하지 않습니다.

is 연산자

ActionScript 3.0에 새로 추가된 is 연산자를 사용하면 변수 또는 표현식이 지정된 데이터 유형의 멤버인지 여부를 테스트할 수 있습니다. 이전 버전의 ActionScript에서 instanceof 연산자가 이 기능을 제공했지만 ActionScript 3.0에서는 instanceof 연산자를 데이터 유형 멤버를 테스트하는 데 사용할 수 없습니다. x instanceof y 표현식으로는 단지 x의 프로토타입 체인에 y가 존재하는지만 확인할 수 있으며, ActionScript 3.0의 프로토타입 체인을 통해서는 완전한 상속 계층 구조에 액세스할 수 없으므로 유형 검사를 수동으로 수행하려면 instanceof 연산자 대신 is 연산자를 사용해야 합니다.

is 연산자는 정확한 상속 계층 구조를 검사하며 객체가 특정 클래스의 인스턴스인지 뿐만 아니라 객체가 특정 인터페이스를 구현하는 클래스의 인스턴스인지 여부를 확인하는 데 사용됩니다. 다음 예제에서는 mySprite라는 Sprite 클래스의 인스턴스를 만들고 is 연산자를 사용하여 mySprite가 Sprite와 DisplayObject 클래스의 인스턴스인지 및 IEventDispatcher 인터페이스를 구현하는지 여부를 테스트합니다.

var mySprite:Sprite = new Sprite();
trace(mySprite is Sprite);                   // true
trace(mySprite is DisplayObject);            // true
trace(mySprite is IEventDispatcher);         // true

is 연산자는 상속 계층 구조를 검사하고 mySprite가 Sprite 및 DisplayObject 클래스와 호환되는지 보고합니다. Sprite 클래스는 DisplayObject 클래스의 하위 클래스입니다. 또한 is 연산자는 mySprite가 IEventDispatcher를 구현하는 클래스에서 상속되는지 여부를 확인합니다. Sprite 클래스가 IEventDispatcher 인터페이스를 구현하는 EventDispatcher 클래스에서 상속되므로 is 연산자는 mySprite가 동일한 인터페이스를 구현하고 있음을 정확하게 보고합니다.

다음 예제에서는 이전 예제와 동일한 테스트를 보여 주지만 is 연산자 대신 instanceof를 사용합니다. instanceof 연산자는 mySprite가 Sprite 또는 DisplayObject의 인스턴스인지를 정확하게 식별하지만 mySprite에서 IEventDispatcher 인터페이스를 구현하는지 여부를 테스트하기 위해 사용하는 경우에는 false를 반환합니다.

trace(mySprite instanceof Sprite);           // true
trace(mySprite instanceof DisplayObject);    // true
trace(mySprite instanceof IEventDispatcher); // false

as 연산자

ActionScript 3.0에 새로 추가된 as 연산자를 사용하면 표현식이 지정된 데이터 유형의 멤버인지 여부를 확인할 수 있습니다. is 연산자와 달리 as 연산자는 부울 값을 반환하지 않습니다. as 연산자는 true 대신 표현식의 값을 반환하고 false 대신 null을 반환합니다. 다음 예제에서는 Sprite 인스턴스가 DisplayObject, IEventDispatcher 및 Number 데이터 유형의 멤버인지 여부를 확인할 때 is 연산자 대신 as 연산자를 사용하는 경우에 대한 결과를 보여 줍니다.

var mySprite:Sprite = new Sprite();
trace(mySprite as Sprite);                 // [object Sprite]
trace(mySprite as DisplayObject);                 // [object Sprite]
trace(mySprite as IEventDispatcher);                 // [object Sprite]
trace(mySprite as Number);                                       // null

as 연산자를 사용하는 경우 오른쪽 피연산자는 데이터 유형이어야 합니다. 오른쪽 피연산자로 데이터 유형이 아닌 표현식을 사용하려고 하면 오류가 발생합니다.


Flash CS3

 

이 페이지에 의견 추가되면 전자 메일 알림 받기 | 의견 보고서

현재 페이지: http://livedocs.adobe.com/flash/9.0_kr/main/00000045.html