インタフェース

interface.png

インターフェースの使い所

たとえばJavaでimplements MouseListenerしないとMouseEventが使えないとか、
java.util.Arraysで自作オブジェクトが要素になってる配列をソートするにはComparableをimplementsしたクラスじゃないとダメとか
あるstaticな関数を使いたいから、これとこれを実装してくれ、というかんじ
つまり、

  • static関数の引数としてインタフェースを使う

インタフェースの利点

  • そのインタフェースを使う側は、オブジェクトの詳細な実装を知らなくても、インタフェースに定義されている関数を呼ぶだけで、簡単に使える。
  • インタフェースを戻り値にしたりする
  • インタフェースを引数にしてなんでも受け入れられるようにしておく

またEffectiveJava[5]ではこんな使い方をおすすめしている

//宣言するときはインタフェース。 定義するときは派生型にする
List<Miffy> mList=new ArrayList<Miffy>();

**ただし、Android上のパフォーマンス的には
ArrayList<Miffy> mList=new ArrayList<Miffy>();//こちらの方が高速

オブジェクト指向になぞらえば、上記のようなケースでは多様性の恩恵を受けるために、Mapインターフェースを使った実装が好まれるが、Androidの実装ではパフォーマンス的にNG。
インターフェースを使う場合、使わない時と比べて2倍近く遅くなることがあります。
ただし、外部へAPIを公開する場合は、パフォーマンスを犠牲にしてでもインターフェースを使うべきケースも出てくるので利用シーンに応じて最適な選択をすべき。

私は以前こんな失敗をした。
3Dオブジェクトを描画するためのインタフェースを作ってみたが、
インタフェースに次々と機能を追加し、
インタフェースを継承した子どもたちが、インタフェースの改修の度にめちゃめちゃにバグり、
使うのがいやになった。

手順としては、

  1. まず具体的なクラスを作ってみる
  2. 複数のクラスの共通点をみつける
  3. インタフェースを作る(なるべく少ないメンバ関数で)

クラスを作るんだから、立派にしないといけないかしら、と心配してたのがそもそもの間違いだった。
多くても3,4個ぐらいの関数でいい。
インタフェースのメンバ関数が1個だけでも全く気にする必要はない。

インタフェースの欠点

  • メンバ変数を置けないところだ。SetやGetを作らないといけないのだ。
  • 兄弟を同じ配列に入れる裏ワザ使えない。

ただの親クラスとの違い

言葉の意味

  1. (二者間の)境界面,接点 〔between〕.
  2. 共通の問題.
  3. 【電子計算機】 インターフェイス 《電算システムにおけるハードウェア同士の接点または接点となるプログラム; 人間と電算システムとの接点,また接点となるプログラムや機器》.

このメソッドを必ず実装するようなクラスを作る、とか忘れないためのひな形作りに良いと思って利用することにした。
オブジェクト指向プログラミングにおいて、複数の種類のオブジェクトに関して共通する機能を実装するためのメッセージの規格を定義したもの。
ポリモーフィズムと同義だと思う。

インタフェースの名前

C++では接頭辞にIをつける、なんて話がある。
JavaではインタフェースはXXXListenerという名前が多い気がする。

書き方

c++とjavaのインターフェースでは意味が違うようだ。javaでいうところのインタフェースの代わりに多重継承がある。
純粋仮想関数を含んでいるクラスはインスタンス化ができない。
継承しないと使えない。
C++では、直接的にインタフェースクラスを記述できず、純粋仮想関数を宣言してやることで、 インスタンス化を妨害するような形で実現させています。
インタフェースクラスには仮想デストラクタを宣言しておくべきらしい。理由は今のところ不明。
コンストラクタはなくてよし
て思ってたけど、ないと変換できないよね?

#ifndef MIFFY_OBJECT_I
#define MIFFY_OBJECT_I
class ISlider{
public:
    virtual ~ISlider(){};//デストラクタはここで定義してしまおう
    virtual string GetTitle()=0;
    virtual void SetVal(float _val)=0;
    virtual float GetVal()=0;
};
#endif
class CMain: public IRenderObject{
void Draw(){//これがないと抽象クラス型CMainのオブジェクトは使用できませんエラーになる
}
void main(){
CMain* mMain=new CMain();
}

しかし、C++ the programming languageでは.hファイルのことをインターフェースと呼んでいる。
もっと言うと、namespaceの内側に入っていて、関数だけ宣言してあるようなものである。
別のファイル.cにあって同じnamespace内で変数が宣言されているものはrepresentationと呼ばれている。[1]

インタフェースの作り方

public インタフェースの場合

これを抽象クラスっていうんだよね?

  • データメンバを入れない。
  • 仮想関数がある

どんなものをインタフェースにする?

まずは、普通のクラスを設計してから、どの関数をインタフェースに入れるか(どの関数は入れないでおくか)考える。[3]
色々なクラスを一つの関数の引数としてまとめて扱いたい時。
たとえば、

エラー

インタフェースのメソッドを使うと実行時エラーになる。

どうも多重継承したときにおこるみたい。
javaみたいに、extends Parent implement Interface
なノリでやってたのになぁ。

参考にした本

ヘッドファースト 頭とからだで覚えるデザインパターンの基本


私的にはこれが一番わかりやすくて楽しく学べる。取り扱ってる例も悪くない。難しいことを楽しそうな口調で書いてくれているので、なんか楽しいことかのように錯覚することができる。悲しい歌詞を楽しい曲調で歌ってる歌を聞くと、前向きになれるみたいに。

オブジェクト指向でなぜつくるのか


この本曰く、オブジェクト指向の勉強がとっつきにくいのは、その人にとって興味のない例を使って説明しようとするからだ、と書いてあったきがする。
その点は激しく納得。
多くのオブジェクト指向の和書は、つまらない会社の業務っぽいシステムを例に出してくる。
学生で、将来会社で働くなんてだせーと思っていた私には激しくつまらなく感じ、身につかなかった。
たしかに、オブジェクト指向は、業務や製品としてのソフトウェアになるほど大事になってくる。
会社で働いてる今でも、業務っぽい例で説明したオブジェクト指向はつまらない。
ゲームでオブジェクト指向を説明してるサイトがあって、それはすっごく面白く感じたし、実用的だと感じたし身についた気がする。

C++ Programming Language


ゲームプログラマになる前に覚えておきたい技術という本で、C++に関してはこれさえあれば他の本は要らないみたいに書かれていて、高いけど頑張って買ったのだが。。。学術的で結構難しい。私は英語版と一緒に参照にしている。C++を作った人が書いた本なので、学術的だけど、必ず正しいしといえる。最近はC++11版が出たらしい。ちょっと待ってそれを買えばよかった。

Effective C++


定番中の定番。
これを理解できたら、プログラマとして一皮向ける。
などと言われている。大変有名な書籍。
正直に言うと私はまだ習得していない。

[[bibliography]]

label
Android高速化Tips

[[/bibliography]]

サポートサイト Wikidot.com