【Android】【Applet】【Java】interface を使って独自のラッパークラスを作る 
2014/06/27 Fri [edit]
前回の「interface と abstract の使い方~簡単なフレームワークを作る」の続きのようなものだが、実際にマルチプラットフォームのようなコードを書いてみようと思うと、少し困ったことが起きる。それはプラットフォーム依存のオブジェクトは、メインコード(プラットフォーム共通のコード)内では使えないという事だ。
その解決方法は独自のラッパークラスを作ることで多少何とかなる。「ラッパークラス」をググると「プリミティブ型をオブジェクト型のように扱いたいとき使うクラス」(int 型に対して Integer 型のような)とあるが、ここではもっと広義に「あるオブジェクトがあったとして、そのオブジェクトと同等の機能を持つクラス」という意味で使っている(本来は、元の型をラッピング(包み込む)から言及している)。それは前回 interface を色々いじっくった人にはもう簡単だろう(笑)。
例として画像オブジェクトの扱いを挙げてみよう。具体的に言えば、Android では Bitmap, Drawable クラス、Applet では Image, BufferedImage クラス等がよく使われるわけだが、これをメインコードに大量に書いてしまっては、もはやプラットフォーム互換コードなど、夢のまた夢である(笑)。とりあえず、それぞれのプラットフォームでのコードの違いを見るために、そのまま書いてみよう。
●Android 版(Bitmap を使う)
//100 x 200 で画像を生成
Bitmap image = Bitmap.createBitmap(100, 200, Config.ARGB_8888);
dispSize(image);
//サイズ表示
public void dispSize(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
System.out.println("width = " + width + " / height = " + height);
}
●Applet 版(BufferedImage を使う)
//100 x 200 で画像を生成
BufferedImage image = new BufferedImage(100, 200, BufferedImage.TYPE_INT_ARGB);
dispSize(image);
//サイズ表示
public void dispSize(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
System.out.println("width = " + width + " / height = " + height);
}
上手くオブジェクトが生成できれば、"width = 100 / height = 200" と出力されるだろう。
サイズを出力するメソッドはオーバーロードすれば、多くの型に対応できるかも知れないが、今回はこのメソッドを共通に使えるように考えてみよう。そのためには、例によって interface を定義して、簡単な独自のラッパークラスを作ってみる。
●簡単な画像ラッパークラス用のインターフェイス (XImage)
public interface XImage {
public void createImage(int width, int height);
public int getWidth();
public int getHeight();
}
●Android 版 画像ラッパーインターフェイスの実装クラス (AndroidImage)
public final class AndroidImage implements XImage {
private Bitmap image;
//コンストラクタ
public AndroidImage() {
}
@Override
public void createImage(int width, int height) {
this.image = Bitmap.createBitmap(width, height, Config.ARGB_8888);
}
@Override
public int getWidth() {
return image.getWidth();
}
@Override
public int getHeight() {
return image.getHeight();
}
}
●Applet 版 画像ラッパーインターフェイスの実装クラス (AppletImage)
public class AppletImage implements XImage {
private BufferedImage image;
//コンストラクタ
public AppletImage() {
}
@Override
public void createImage(int width, int height) {
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
@Override
public int getWidth() {
return image.getWidth();
}
@Override
public int getHeight() {
return image.getHeight();
}
}
あくまでも概要を把握して貰うために、例外処理や空のコンストラクタなど、割愛してるので色々問題はあるが、だいたい想像付いたのではないだろうか?そう、前回の XFiler の定義の考え方とあまり変わらない。XFiler ではメソッドを loadTextFile() で統一化したが、今回は Bitmap や BufferedImage をクラスの中に隠して、メソッドでアクセスしているだけだ。Bitmap と BufferedImage は仕様が似ているので採用した。なるべく同じような仕様のオブジェクトで構成した方が、互換性は高くなる。
これでメソッド部分だけは共通に使えるようになった。
●画像のサイズを出力するメソッドの引数をインターフェイス(XImage)に統一する
//サイズ表示
public void dispSize(XImage xImg) {
int width = xImg.getWidth();
int height = xImg.getHeight();
System.out.println("width = " + width + " / height = " + height);
}
そして、はじめのメインコードを書き換えてみよう。
●Android 版 画像ラッパークラス(AndroidImage)を使ったメインコード
//インスタンスを生成
XImage xImg = new AndroidImage();
//100 x 200 で画像を生成
xImg.createImage(100, 200);
dispSize(xImg);
●Applet 版 画像ラッパークラス(AppletImage)を使ったメインコード
//インスタンスを生成
XImage xImg = new AppletImage();
//100 x 200 で画像を生成
xImg.createImage(100, 200);
dispSize(xImg);
インスタンスを生成する部分以外は共通化できたようだ。コンストラクタに難がある気がするが、それは諸事情(笑)で後回しにする。
この例は大したものではないので、あまり利用価値はないだろうが、メソッドのプラットフォーム依存を無くすことだけでも、再利用の幅が広がる事が想像できるのではないだろうか?特にグラフィック関数などは、プラットフォームによってメソッド名や引数など、結構違うものだが、やってることはほとんど変わらないので、こういった手法で、どちらでも使えるメソッドを作る事も可能だ。これも interface の1つの利用方法だろう。下にあるサンプルデモもそうやって作ったものである。
次回は1箇所だけ残ってしまった共通化できない部分、インスタンス生成コードを interface を使って、プラットフォーム依存を軽減してみよう。
サンプルデモ:Rule Generator Demo
Applet 版のサンプル (PC[IE]でアクセス)
Android 版のサンプル (Android2.2以降でアクセス)
(解説) Android と Applet の互換ってできるもんだね
(関連記事)
【Android】【Applet】【Java】interface と abstract の使い方・違いとは~簡単なフレームワークを作って、考えてみる
【Android】【Applet】【Java】interface を使ってインスタンスを生成する
【Java】interface を使って簡単なコールバック機能を作る
【Android】【Java】clone() を使ったオブジェクト複製
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/128-7d6f30c0
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |