インターフェイス
インターフェイスは、関連しないオブジェクトの相互の通信を可能にするメソッド宣言の集合です。 例えば、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 インターフェイスを実装する他のオブジェクトに渡します。
インターフェイスは、クラスのようにデータ型を定義すると説明することもできます。 したがって、インターフェイスはクラスのように型注釈として使用できます。 インターフェイスは、データ型として is 演算子や as 演算子などのデータ型を必要とする演算子と使用することもできます。しかし、クラスとは異なり、インターフェイスをインスタンス化することはできません。 この違いから、多くのプログラマーは、インターフェイスを抽象データ型、クラスを具象データ型と見なしています。
インターフェイスの定義
インターフェイス定義の構造は、クラス定義の構造に似ていますが、インターフェイスにはメソッド本体のないメソッドしか含めることができません。 インターフェイスに変数や定数を含めることはできませんが、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 アクセス制御修飾子で宣言されます。インターフェイス定義は、public および internal アクセス制御指定子でのみ変更できます。インターフェイス定義内のメソッド宣言には、アクセス制御指定子を使用できません。
ActionScript 3.0 では、インターフェイス名は大文字の I で始まるという表記規則に従いますが、インターフェイス名には有効な任意の識別子を使用できます。インターフェイス定義は、通常パッケージのトップレベルに配置されます。 クラス定義内または別のインターフェイス定義内に、インターフェイス定義を配置することはできません。
インターフェイスは、他のインターフェイスを拡張できます。 例えば、次のインターフェイス、IExample は、IExternalizable インターフェイスを拡張します。
public interface IExample extends IExternalizable
{
function extra():void;
}
IExample インターフェイスを実装するクラスはいずれも、extra() メソッドの実装だけでなく、IExternalizable インターフェイスから継承される writeExternal() および readExternal() メソッドの実装も含む必要があります。
クラス内でのインターフェイスの実装
クラスは、インターフェイスを実装できる唯一の ActionScript 3.0 言語エレメントです。 クラス宣言内で implements キーワードを使用して、1 つまたは複数のインターフェイスを実装します。次の例では、IAlpha および IBeta の 2 つのインターフェイスと、これらの両方を実装する 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 {}
}
インターフェイスを実装するクラスでは、実装されたメソッドは以下を行う必要があります。
実装するメソッドのパラメーターには、ある程度自由に名前を付けることができます。 実装されるメソッドとインターフェイスメソッドのパラメーター数および各パラメーターのデータ型は一致する必要がありますが、パラメーター名を一致させる必要はありません。 例えば、前の例では 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 {}
}
この柔軟性は、インターフェイスを実装する規則がデータ型の互換性を確保するように特別に設計されているからです。このために、同じパラメーター名およびデフォルトのパラメーター値を要求する必要はありません。