かんたんなJava入門これからJavaを始めようという人の為の超入門サイトです。かんたんなJava入門twitter4facebook0hatenabookmark00lineインターフェースって何なのかイマイチよく分からないという人に向けて、その概念や使い方、使いどころについて説明します。定義できるもの多重継承インターフェースと抽象クラスの違いまとめインターフェースと継承インターフェースを理解するには先に継承や抽象クラス(abstract)について理解しておいた方がいいです。そこらがまだよく分かっていていない人は先に継承って何?辺りから読み直すことをおすすめします。今までクラスを書いてきましたが、クラスというのは何らかのパラメータや機能を持つオブジェクトを作るために書くのでした。具体的に言うと「食事をできる人間」だとか、「走れる車」だとかっていう風に、あくまで人間であったり車であったり、何らかのオブジェクトを作るために書くのがクラスです。あるクラス(オブジェクト)を元に、より限定的(専門的)な機能を備えたオブジェクトを作ることができるのが継承です。具体的には「プログラミングができる人間(プログラマー)」だとか、「速く走れる車」とかっていう風に。それに対し、インターフェースというのは、言わば何らかの機能だけを抽出したような存在です。言葉にするなら「プログラミングができる」とか、「速く走れる」みたいに、オブジェクトから分離した状態で、その機能だけを取り出して定義するのがインターフェースだと思っていたらいいです。インターフェースは、オブジェクトと分離した存在なので、いろんなオブジェクトにその機能だけをくっつけることができます。インターフェースが持つ機能をあるクラスにくっつけることを「実装する」なんていう風に表現します。継承の場合は、extendsというのを使いましたね。Super{}それに対して、インターフェースを実装する時は、implementsを使います。runnable{}↑Humanクラスにrunnableインターフェースを実装しています。走れる人間オブジェクトです。「runnable」というのは「run(走る)」に可能の「able」がくっついた英単語です。インターフェース名はしばしばこのように機能を表す動詞+ableという名称が使われます。継承との大きな違いとして、インターフェースはいくつでも実装することができます。複数のインターフェースを実装するにはコンマ区切りで列挙するだけです。flyable{}↑これで、走れて泳げて空を飛べる人間オブジェクトです。継承とインターフェースを両方使うこともできます。flyable{}↑空を飛べる車(スーパーカー)オブジェクトです。インターフェースの定義の仕方インターフェースの定義の仕方は普通のクラスを定義するのとよく似ています。以下はFlyableインターフェースを定義しています。fly();}Flyableインターフェースのメンバはflyメソッドのみです。flyメソッドの中身は定義されていません。この形、見覚えありますよね?abstractの説明で出てきた形です。インターフェースもabstractなメソッドと同じで、具体的な処理の中身はその場では定義せず、実装先のクラスで定義します。要するに「Flyableインターフェースを実装したらflyメソッドが呼ばれるだろうから、飛べるように各自用意しておきなさいよ。」という約束事を徹底させるのがインターフェースの役割と言えます。HumanクラスにFlyableインターフェースを実装してみます。}}実際に、Humanオブジェクトを飛ばしてみましょう。先程はインターフェースとは機能を抽出したものと言いましたが、実際は具体的な機能については実装する際にそれぞれのクラスにて定義する必要があるわけです。枠だけを提供するような感じですね。Flayableインターフェースを実装したクラスはflyメソッドを定義しなければコンパイルが通りません(注*)。言い方を変えると、Flyableインターフェースを実装しているクラスは、flyメソッドが呼ばれたら飛ぶことが保証されているクラスだということです。注*)抽象クラスにして継承先に定義を先送りすることはできます。Nobuoが飛んだとかそんなこと言われても、インターフェースの使い所がイマイチよく分からないと思うので、続いてもう少し実践的な例で説明します。ポリモーフィズムとは?インターフェースの使い所を理解するにはポリモーフィズム(多態性)という概念とセットで考える必要があるかと思います。ポリモーフィズムの定義なんて言葉で説明されてもチンプンカンプンだと思うので、それがなんとなく分かるような例を出して説明します。アプリとそれが動くプラットフォーム(OS)の設計を想像しましょう。画面に配置できるパーツをビューと呼び、Viewクラス(抽象クラス)で定義されているものとします。Viewインスタンスはそのビューのサイズをパラメータとして持つものとします。}}このViewクラスを継承した以下のようなクラスで、実際に画面に配置されるビューを定義します。TextViewクラス(ただのテキスト)ImageViewクラス(画像を表示する為のビュー)ButtonViewクラス(ボタン)TextViewクラスはこんな感じです。}}TextViewクラスは表示する文字(テキスト)に関する情報をパラメータとして持ちます。ImageViewクラスはこんな感じです。}}ImageViewクラスは表示する画像リソースのuriをパラメータとして持ちます。ところで、ビューにはクリックできるものと、クリックしても何の反応もないものがありますね。クリックできるものはClickableインターフェースでその機能を付随させましょう。onClick();}Clickableインターフェースを実装したクラス(ビュー)は必ずそのビューがクリックされた際の処理(onClickメソッド)を定義する必要があります。クリックして反応があるものと言えば、ボタンですね。ButtonViewクラスは文字列情報も持っているべきなのでTextViewクラスを継承しつつClickableインターフェースを実装することで、ボタン機能を表現しましょう。"がクリックされました。}}と、こんな風なクラス設計にしておけば、クリックされた際の挙動に関してはそれぞれのアプリ側でonClickメソッドによって定義することができ、システム側では「ビューのクリック検知→そのビューインスタンスのonClickメソッドを呼ぶ」という非常にシンプルかつ統一的な処理でクリック時の反応を制御することができます。テキストボタンではなく画像ボタンを作ろうと思えば、ImageViewを継承したImageButtonViewクラスを作ってClickableインターフェースを実装させればOKです。}}Clickableインターフェースを実装しているならonClickメソッドが定義されていることが保証されているので、システム側はどんなビューであれClickableインターフェースを実装しているビューならば、安心してonClickメソッドを呼ぶことが出来るわけです。clickableなビューです。このように、呼ぶ側からすれば共通のメソッド(ここで言うonClickメソッド)で定義しながらも、それぞれのクラスごとに独自の動作(処理)を定義するプログラミング手法をポリモーフィズムとか多態性と呼んでいます。抽象クラス(abstract)やインターフェースという仕組みは、多態性(ポリモーフィズム)を上手く実現するための手段だと言えます。インターフェースと抽象クラスインターフェースと抽象クラスは機能的によく似ている部分が多いです。一方で決定的に違う部分もあります。その微妙な違いをまとめておきます。アクセス修飾子インターフェースに付けられるアクセス修飾子はpublicだけです。インターフェースっていうのは他のクラスに実装することを前提に書いているんだからprivateにするって意味がわかりません。publicをつけなかった場合(アクセス修飾子なし)、同パッケージ内からの利用だけに制限されることになります。抽象クラスはpublicだけでなくprotectedも付けることができます。protectedはサブクラスからしかアクセスできない状態です。定義できるものインターフェースの中では変数(いわゆるパラメータ)は定義できません。finalなクラス定数のみです。finalな変数(クラス定数)として扱われます。メソッドに関しては、インターフェース内で定義できるのは中身のないメソッド、つまり抽象メソッドだけ。Java8からdefault修飾子を付けることで中身も定義できるようになりました。メソッドに付けられるアクセス修飾子はpublicのみです。メソッドにpublicを付けても付けなくても結局インターフェース自体の修飾子が優先されるので、付ける意味がありません。抽象クラスのメンバは、特に制限なく普通のクラスと同じように変数もメソッドも定義することができます。いうよりそもそも抽象クラスとは一つでもabstractなメソッドがあれば抽象クラスになるってだけの話です。抽象クラスの継承(抽象クラスでなくても)の場合は、一つのクラスに対して親クラスとなれるのは一つだけです。