인터페이스

인터페이스는 관련되지 않은 여러 객체가 서로 통신할 수 있게 하는 메서드 선언을 모아 놓은 것입니다. 예를 들어 ActionScript 3.0에는 클래스에서 이벤트 객체를 처리하는 데 사용할 수 있는 메서드 선언이 들어 있는 IEventDispatcher 인터페이스가 정의되어 있습니다. 여러 객체는 IEventDispatcher 인터페이스를 통해 표준화된 방식으로 이벤트 객체를 서로 전달할 수 있습니다. 다음 코드에서는 IEventDispatcher 인터페이스의 정의를 보여 줍니다.

public interface IEventDispatcher 
{ 
    function addEventListener(type:String, listener:Function,  
            useCapture:Boolean=false, priority:int=0, 
            useWeakReference:Boolean = false):void; 
    function removeEventListener(type:String, listener:Function,  
            useCapture:Boolean=false):void; 
    function dispatchEvent(event:Event):Boolean; 
    function hasEventListener(type:String):Boolean; 
    function willTrigger(type:String):Boolean; 
}

인터페이스는 메서드의 인터페이스와 해당 구현이 서로 구분된다는 점을 기반으로 합니다. 메서드의 인터페이스에는 해당 메서드를 호출하는 데 필요한 메서드 이름, 모든 매개 변수 및 반환 유형 등의 모든 정보가 포함됩니다. 메서드 구현에는 인터페이스 정보뿐만 아니라 메서드의 비헤이비어를 수행하는 실행 가능한 명령문도 포함됩니다. 인터페이스 정의에는 메서드 인터페이스만 들어 있으며, 해당 인터페이스를 구현하는 모든 클래스에서는 메서드 구현을 정의해야 합니다.

ActionScript 3.0의 EventDispatcher 클래스에서는 모든 IEventDispatcher 인터페이스 메서드를 정의하고 각 메서드에 본문을 추가하여 IEventDispatcher 인터페이스를 구현합니다. 다음은 EventDispatcher 클래스 정의에서 인용한 코드입니다.

public class EventDispatcher implements IEventDispatcher 
{ 
    function dispatchEvent(event:Event):Boolean 
    { 
        /* implementation statements */ 
    } 
 
    ... 
}

IEventDispatcher 인터페이스는 EventDispatcher 인스턴스에서 이벤트 객체를 처리하고 마찬가지로 IEventDispatcher 인터페이스를 구현하는 다른 객체로 이벤트 객체를 전달하는 데 사용되는 프로토콜 역할을 합니다.

또한 인터페이스는 클래스와 마찬가지로 데이터 유형을 정의합니다. 따라서 클래스와 마찬가지로 인터페이스를 유형 약어로 사용할 수 있습니다. 인터페이스는 데이터 유형이므로 데이터 유형이 필요한 isas 등의 연산자와 함께 사용할 수 있습니다. 그러나 클래스와 달리 인터페이스는 인스턴스화할 수 없습니다. 이러한 차이점으로 인해 인터페이스를 추상적인 데이터 유형으로, 클래스를 구체적인 데이터 유형으로 간주하는 프로그래머가 많습니다.

인터페이스 정의

인터페이스 정의의 구조는 클래스 정의의 구조와 비슷하지만 인터페이스에는 본문이 없는 메서드만 포함될 수 있습니다. 인터페이스에는 변수 또는 상수가 포함될 수 없지만 getter 및 setter는 포함될 수 있습니다. 인터페이스를 정의하려면 interface 키워드를 사용합니다. 예를 들어 다음 IExternalizable 인터페이스는 ActionScript 3.0의 flash.utils 패키지에 속합니다. IExternalizable 인터페이스에서는 객체를 직렬화하는 프로토콜을 정의합니다. 직렬화란 객체를 장치에 저장하거나 네트워크를 통해 전송하는 데 적합한 형식으로 변환하는 것입니다.

public interface IExternalizable 
{ 
    function writeExternal(output:IDataOutput):void; 
    function readExternal(input:IDataInput):void; 
}

IExternalizable 인터페이스는 public 액세스 제어 수정자와 함께 선언되어 있습니다. 인터페이스 정의에는 publicinternal 액세스 제어 지정자만 사용할 수 있습니다. 인터페이스 정의 내부의 메서드 선언에는 액세스 제어 지정자를 사용할 수 없습니다.

ActionScript 3.0에서는 인터페이스 이름을 대문자 I로 시작하는 규칙을 따르고 있지만, 모든 유효한 식별자를 인터페이스 이름으로 사용할 수 있습니다. 인터페이스 정의는 패키지의 최상위 수준에 배치되는 경우가 많습니다. 클래스 정의 내부나 다른 인터페이스 정의 내부에는 인터페이스 정의를 배치할 수 없습니다.

인터페이스는 하나 이상의 다른 인터페이스를 확장할 수 있습니다. 예를 들어 다음 IExample 인터페이스에서는 IExternalizable 인터페이스를 확장합니다.

public interface IExample extends IExternalizable 
{ 
    function extra():void; 
}

IExample 인터페이스를 구현하는 모든 클래스에는 extra() 메서드뿐만 아니라 IExternalizable 인터페이스에서 상속된 writeExternal()readExternal() 메서드에 대한 구현도 포함되어야 합니다.

클래스에서 인터페이스 구현

클래스는 인터페이스를 구현할 수 있는 유일한 ActionScript 3.0 언어 요소입니다. 하나 이상의 인터페이스를 구현하려면 클래스 선언에 implements 키워드를 사용합니다. 다음 예제에서는 IAlpha 및 IBeta라는 두 인터페이스를 정의하고, 두 인터페이스를 모두 구현하는 Alpha라는 클래스를 정의합니다.

interface IAlpha 
{ 
    function foo(str:String):String; 
} 
 
interface IBeta 
{ 
    function bar():void; 
} 
 
class Alpha implements IAlpha, IBeta 
{ 
    public function foo(param:String):String {} 
    public function bar():void {} 
}

인터페이스를 구현하는 클래스에서 구현된 메서드는 다음 조건에 맞아야 합니다.

  • public 액세스 제어 식별자를 사용해야 합니다.

  • 인터페이스 메서드와 같은 이름을 사용해야 합니다.

  • 매개 변수 개수가 같아야 하고 각 매개 변수의 데이터 유형이 인터페이스 메서드 매개 변수의 데이터 유형과 일치해야 합니다.

  • 같은 반환 유형을 사용해야 합니다.

    public function foo(param:String):String {}

그러나 구현하는 메서드의 매개 변수 이름은 융통성 있게 지정할 수 있습니다. 구현된 메서드에서 매개 변수 개수 및 각 매개 변수의 데이터 유형은 인터페이스 메서드와 일치해야 하지만 매개 변수 이름은 일치하지 않아도 됩니다. 예를 들어 이전 예제에서 Alpha.foo() 메서드의 매개 변수 이름은 param입니다.

그러나 IAlpha.foo() 인터페이스 메서드에서는 매개 변수 이름이 str입니다.

function foo(str:String):String;

매개 변수 기본값도 유연하게 지정할 수 있습니다. 인터페이스 정의에는 매개 변수 기본값이 지정된 함수 선언이 포함될 수 있습니다. 이러한 함수 선언을 구현하는 메서드에는 인터페이스 정의에 지정된 값과 데이터 유형이 같은 매개 변수 기본값이 있어야 하지만 실제 값은 일치하지 않아도 됩니다. 예를 들어 다음 코드에서는 매개 변수 기본값이 3인 메서드가 들어 있는 인터페이스를 정의합니다.

interface IGamma 
{ 
    function doSomething(param:int = 3):void; 
}

다음 클래스 정의에서는 IGamma 인터페이스를 구현하지만 다른 매개 변수 기본값을 사용합니다.

class Gamma implements IGamma 
{ 
    public function doSomething(param:int = 4):void {} 
}

이러한 유연성을 발휘할 수 있는 이유는, 인터페이스 구현에 대한 규칙이 데이터 유형의 호환성을 보장하기 위해 설계되었으며 이를 위해 매개 변수 이름과 매개 변수 기본값이 항상 일치할 필요는 없기 때문입니다.