(メインページへ)
4.ActionScript2.0のオブジェクト指向プログラミング/4.5 インターフェイス

4.5 インターフェイス

インターフェイスとは

インターフェイスとは、クラス定義を行うときの約束事として、クラスが必ず実装しなければならないメソッドを指定した仕様書のようなものです。
たとえば、ロケットとその発射装置を開発するとき、「ロケットはfire信号で点火するように開発するから、発射装置はロケットにfire信号を送れるように作ってくれればよい」というような仕様の取り決めさえあれば、ロケットと発射装置の開発は互いの内部処理はまったく知らなくとも別々に進めることができます。もし、ロケットの打ち上げに失敗しても、次のロケットも同じようにfire信号で点火するように作ってあれば、同じ発射装置で飛ばすことができます。ここに
 1.ロケットの仕様
 2.発射装置の仕様
 3.インターフェイスの仕様
の3つの仕様が存在することに気付きます。そしてロケットと発射装置はインターフェイスの仕様を共有していることがわかります。

個別リンク | コメント (0) | トラックバック

インターフェイスの定義

これをActionScriptで書くと次のようになります。インターフェイスはinterfaceキーワードで定義します。インターフェイスで指定できるのはメソッドだけで、プロパティの指定やfunctionブロックなどを書くことはできません。

sample→ex04-05/interfaceフォルダ

インターフェイス定義:RocketInterface.as
interface RocketInterface {
function fire():Void;
}

インターフェイスの取り決めを守るクラスでは、implementsキーワードでインターフェイス定義ファイルを指定し、実際にインターフェイスで指定されているメソッドを実装します。インターフェイスを指定しているにも関わらず、インターフェイスで指定されているメソッドを実装していなかったり、メソッドの引数や戻り値のデータ型が一致していないとコンパイルエラーになります。インターフェイスRocketInterfaceを使うクラスRocket1は次のようなクラス定義になります。

インターフェイスを守るクラス定義:Rocket1.as
class Rocket1 implements RocketInterface {
//コンストラクタ
function Rocket1() {
}
//インターフェイスで取り決められているメソッド
function fire():Void {
trace("ロケット点火処理");
}
/*
以下、ロケット1号機の内部処理が続く
*/
}


同様に別の開発者はインターフェイスRocketInterface.asを譲り受ければロケット2号機の開発に着手できます。

インターフェイスを守るクラス定義:Rocket2.as
class Rocket2 implements RocketInterface {
//コンストラクタ
function Rocket2() {
}
//インターフェイスで取り決められているメソッド
function fire():Void {
trace("ロケット点火処理");
}
/*
以下、ロケット2号機の内部処理が続く
*/
}

一方、Rocket1クラス、Rocket2クラスと連携する発射装置側のLauncherクラスは次のように定義することができます。

クラス定義:Launcher.as
class Launcher {
var myRocket;
//コンストラクタ
function Launcher(rocket) {
myRocket = rocket;
}
//ロケットに点火する
function startrocket():Void {
/*
準備処理
*/
//点火
myRocket.fire();
}
/*
以下、発射装置の内部処理が続く
*/
}

実際のテストはフレームアクションで次のように行うことができます。

フレームアクション:rockettest.fla
//ロケット1号機を作る
var rocket:Rocket1 = new Rocket1();
//発射台にセット
var theLauncher:Launcher = new Launcher(rocket);
//点火
theLauncher.startrocket(); // 出力→ ロケット点火処理


note:
インターフェイスは、インターフェース、インタフェースと多様な日本語表記が流通しています。サイト等の検索の際には注意してください。

個別リンク | コメント (0) | トラックバック

複数のインターフェイスを適用する

先の例ではインターフェイスで指定しているメソッドが1つでしたが、複数個のメソッドを指定でき、メソッドの引数やデータ型なども指定できます。また、implementsでは複数のインターフェイスファイルを同時に指定できます。たとえば、RedBook、YellowBookという2つのインターフェイスを守るMainClassクラスのクラス定義は次のようになります。

sample→ex04-05/interface2フォルダ

インターフェイス定義ファイル:RedBook.as
interface RedBook {
function redMethod1():Void;
function redMethod2():Void;
}

インターフェイス定義ファイル:YellowBook.as
interface YellowBook {
function yellowMethod1():Void;
}

インターフェイスを守るクラス定義:MainClass.as
class MainClass implements RedBook, YellowBook {
//コンストラクタ
function MainClass() {
}
//インターフェイスに基づいて実装するメソッド
function redMethod1():Void {
//処理a
}
function redMethod2():Void {
//処理b
}
function yellowMethod1():Void {
//処理c
}
/*
その他の処理
*/
}

個別リンク | コメント (0) | トラックバック

インターフェイスのクラスパス

インターフェイス定義ファイルがサブフォルダに入っている場合には、クラス定義ファイルと同じようにクラスパスを指定しなければなりません。インターフェイス定義ファイルをサブフォルダに入れてパッケージとして整理する方法もクラス定義ファイルの場合と同じです(クラスパス→p.??、パッケージ→p.??)。RedBook、YellowBookのインターフェイス定義ファイルがrulebookフォルダに入っている場合は次のようになります。


sample→ex04-05/interfacepathフォルダ

MainClass.as
rulebookフォルダ
 ├ RedBook.as
 └ YellowBook.as


インターフェイス定義ファイル:RedBook.as
interface rulebook.RedBook {
function redMethod1():Void;
function redMethod2():Void;
}


インターフェイス定義ファイル:YellowBook.as
interface rulebook.YellowBook {
function yellowMethod1():Void;
}


インターフェイスを守るクラス定義:MainClass.as
import rulebook.*;
class MainClass implements RedBook, YellowBook {
//コンストラクタ
function MainClass() {
}
//インターフェイスに基づいて実装するメソッド
function redMethod1():Void {
//処理a
}
function redMethod2():Void {
//処理b
}
function yellowMethod1():Void {
//処理c
}
/*
その他の処理
*/
}

個別リンク | コメント (0) | トラックバック

インターフェイスの継承

インターフェイスはクラスと同様にextrendsキーワードを使ってほかのインターフェイスを継承することができます。たとえば、GreenRuleインターフェイスがWhiteRuleインターフェイスを継承しているとき、GreenRuleインターフェイスを採用しているMyClassクラスはGreenRuleインターフェイスとWhiteRuleインターフェイスの両方のメソッドを実装しなければなりません。

sample→ex04-05/extendsフォルダ

インターフェイス定義ファイル:WhiteRule.as
interface WhiteRule {
function whiteMethod(v:Number):Number;
}


インターフェイス定義ファイル:GreenRule.as
//WhiteRuleインターフェイスを継承してる
interface GreenRule extends WhiteRule {
function greenMethod(s:String):Void;
}


インターフェイスを守るクラス定義:MyClass.as
class MyClass implements GreenRule {
var myS:String;
//コンストラクタ
function MyClass() {
}
//インターフェースに基づいて実装するメソッド
function whiteMethod(v:Number):Number {
var x = v * 2;
return x;
}
function greenMethod(s:String):Void {
myS = s;
}
}

個別リンク | コメント (0) | トラックバック

データ型としてのインターフェイス

あるクラスが指定のインターフェイスに基づいているかどうかを調べることができます。インターフェイスに基づいていれば指定のメソッドを実装していることになり、安心してメソッドを呼び出すことができます。
インターフェイスに基づいているかどうかは、RocketInterface(myRocket)のようにインターフェイス(インスタンス)のようにキャスト式を実行したときの戻り値で判定できます(キャスト→p.??)。インターフェイスを実装するインスタンスならばインスタンスがそのまま返り、実装してない場合はnullが返ってきます。


sample→ex04-05/interfacecheckフォルダ

class Launcher2 {
var myRocket;
//コンストラクタ
function Launcher2(rocket) {
myRocket = rocket;
}
//ロケットに点火する
function startrocket():Void {
//インターフェイスが実装されているならば点火する
if (RocketInterface(myRocket) != null) {
myRocket.fire();
}
}
}

個別リンク | コメント (0) | トラックバック