インタフェースについて
インタフェースとは、ある特定の機能の概要を記述したものです。
たとえば、下の図のような関係を考えます。

三角形、四角形はともに「図形」であり、図形の基本的な性質「辺がある」「頂点がある」を
受け継いでます。これは継承のときに説明しました。しかし、「面積の求め方」、「辺の長さの合計」
などはどうでしょうか。三角形、四角形ごとに異なりますよね?図形のスーパークラスで決定できる
ことではないのです。ということはサブクラス(三角形、四角形)で必ず拡張定義しなければ
なりません。そうしないと面積を求める処理で動かなくなってしまいます。なにか
サブクラスで拡張定義することを強制する方法はないのでしょうか?
そこで考え出されたのがインタフェースなのです。
インタフェースの使い方
まず、サブクラスに実装させたいメソッドをまとめます。ここでは面積を求めるメソッドgetArea
(返り値int)を実装させたいとします。ここではクラスとしてではなく、インタフェースとして
プログラミングします。次のように記述します。
public interface zukeiMenseki{
}
1行目は「zukeiMensekiと言う名前のインタフェースを宣言します」という意味です。
2行目で実装させたいメソッドgetAreaを宣言しています。内容は空に
しておきます。なぜなら必ずサブクラスで拡張させるため、記述する
必要が無いからです。(確か記述したらエラーになったような気がする)
次に実装先のクラスを記述します。1行目を注意してください。
public class Triangle implements zukeiMenseki{
・・・
public int getArea(){
}
・・・
}
implements zukeiMensekiとあります。これは「インタフェースを使いますよ」という
部分です。zukeiMensekiというのは先ほど作成したインタフェースの名前です。
そして必ずgetAreaメソッドを定義しなければいけません。宣言しないとエラーに
なります。今回は内容は省略します。実装方法だけ記述しました。
継承との違い
実は継承もインタフェースと言う考え方も、「既存のクラス・メソッドを再利用する」という
目的があります。では相違点はどこでしょうか。最大の違いは継承はひとつの場所からしか
出来ないのにたいし、インタフェースはいくつでも実装することができます。
また継承は既存のクラスのメソッドの内容をそのまま使用するのに適しています。
例えば継承の練習問題で作成したFigureクラスのgetT_suメソッドは
そのまま使うことができるので継承させるほうが効率よくできるでしょう。
一方、今回のような「面積を求める」getArea()メソッドのように、サブクラスごとに異なり、
必ず拡張定義をさせたい時にはインタフェースが適していると言えるでしょう。
ただインタフェースには問題があります。それはインタフェース内で記述したメソッド
は全て実装させなければなりません。例えば3つメソッドがあって、1つは必ず実装させたいが、
2つは必要に応じて拡張すればいい場合とかは困りますよね。継承にしてしまうと
必ず実装させたいメソッドが記述されないことがあります。また、インタフェースにすると
2つの必要に応じて拡張すればいいメソッドまで拡張しなければなりません。
そこで登場するのが継承の時に説明した「abstract」です。これを必ず実装させたいメソッドの
返り値の前(int等)に付けます。そしてこのクラスを継承させればよいのです。
これを行うことによって、1つのみ実装を強制させることができます。
JAVAの考え方は素晴らしいものがあります。
クラスとインタフェース
結局、インタフェースやらクラスやらいろいろ言ってきました。忘れてはいけないのが
クラスとインタフェースの存在目的です。そういう観点からするとクラスもインタフェースも
「既存のプログラムを再利用しやすくする・保守しやすくする」という目的は一緒なわけです。
私達はimplementsとかそのインタフェースの使い方やどういったときに使うというのを
勉強しています。ただ本来の目的を忘れてクラスとインタフェースを乱用して再利用しにくい
プログラムを作ってしまっては本末転倒です。とりあえずこの目的というのものを頭に
いれながら、クラスとインタフェースを利用するようにしましょう。
練習問題
問1
「前に進む」というforwardAdvanceメソッド(引数:なし戻り値:void)を実装するためのNorimono
インタフェースを作成しなさい。
問2
自動車のクラスCarと二輪車のクラスBikeと自転車のクラスBicycleを作成しなさい。
なお
この3つのクラスには問1で作成したインタフェースを実装すること。
なお、forwardAdvanceメソッドは空のままでよい。
問3
上記の「インタフェースの説明」で出てきたインタフェースについて、辺の長さの求め方も図形
(三角形、四角形など)によって異なると説明した。辺の長さの求め方を記述したメソッド
figureLength(引数:なし戻り値:int)を実装するためのZukeiLengthインタフェースを作成しなさい。
問4
前回の講座「スーパークラスとサブクラス」の練習問題 問2 2)で、abstractを使った
プログラムを解答ととして掲載した。
前回の問題
ではこのプログラムRectangle.javaとTriangle.java(変更後)をabstractを使わずに記述するには
どうすればよいか?またgetAreaメソッドは 前回と同じく、必ずサブクラス(下のクラス
今回の例で行くとRectangle.javaとTriangle.java)に実装させるものとする。
ヒント:インタフェースを使う。
解答