Java

【Java】抽象クラスとインターフェースの使い方・メリットを真剣に解説

抽象クラスやインターフェースを使えるということは非常に大事ですので、必ず理解する必要があります。

なので今回は、「これって便利!」と思える例をいくつか紹介していきます。

Human(人)という抽象概念

「たろう君」や「ゆいさん」、「Johnさん」に「Marryさん」。

この人たちは全員「人」です。

しかし、全員「人」でありながら名前や性格、身長・体重、立ち居振る舞いなどは多種多様です。

「たろう君」は「たろう君」、「ゆいさん」は「ゆいさん」です。

つまり、「人」というのは大まかなものを指す言葉で、「たろう君」個人を指すものではありません。

なので、プログラム上に「人」を表現する際も、「たろう君」、「ゆいさん」、「Johnさん」「Maryさん」の4人それぞれの固有なクラスやメンバ変数を設定してあげる必要があります。

しかしこの考え方はプログラミングにとっては敵なのです。

100人の人がいれば100人分のクラスが必要ですし、10000人いれば10000人分のクラスを作らなければいけません。

こうなると、プログラムが非常に煩雑になってしまい、メンテナンスどころか、読むことすらできません。

ではどうすればいいのかというと、抽象クラスを使います。

なので、次は抽象クラスを使わないプログラムと、使った時のプログラムを比較していき、実際にどういうプログラムになっていくのかを見ていきましょう。

抽象クラスを使わないプログラム

では、「たろう君」、「ゆいさん」、「Johnさん」、「Marryさん」の4人のクラスを作ってあげましょう。

(Main.java)

4人分のクラスを定義するための文量は仕方ないとして、「main」関数内は良くないプログラムができました。

4人にただ挨拶をしてもらうだけなので、今は大した文量ではないのですが、もしこれが100人だったらかなり骨が折れそうです。

4人のために変数を作り、4人のために「hello」を4回呼び出しています。

これは非常に煩雑になりやすく、骨が折れやすいプログラムなので、推奨されません。

抽象クラスを使ったプログラム

先ほどの反省を生かし、一番最初に紹介した「人」という抽象概念を作りたいと思います。

つまり、「Human」抽象クラスを作ります。

(Main.java)

抽象クラスを宣言するには、「class」の前に「abstract」と記述します。
先ほどと変わったのは、すべてのクラスに「Human」抽象クラスが拡張(extends)されていることです。

そして各クラス内の「hello」関数の前に、「@Override」という記述が増えました。

この「@Override」自体は書かなくてもいいのですが、明示したほうが保守性が高くなるので、記述することを推奨します。

 

まず、「Human」抽象クラスには宣言だけされている「hello」関数があります。

そして、各クラスでその「hello」関数の中身を実装します。

これだけだと抽象クラスの使い方の紹介になってしまうのですが、注目すべきは「main」関数内です。

抽象クラスを使っていない時のプログラムと比べてどうでしょうか。

「hello」関数を呼び出す回数がたった1回になりましたよね。

さらに言うと、宣言した変数の数も1個になり、「Human」抽象クラスの配列変数にまとめられました。

こうすることによって、新しい「人」を作っても、「human」配列変数の中身に追加するだけなので、「main」関数内に書く処理が大幅に減って、保守性と可読性が向上します。

これが抽象クラスの最大の利点です。

複数の機能を備えたクラスを作成

インターフェースを使うことで、複数の機能を備えたクラスを作成することが可能になります。

例えば、四則演算(+、−、×、÷)が可能な「Calc」クラスを作成するとします。

その時に必要となるインターフェースは計4つ。

「Add」、「Sub」、「Mul」、「Div」という名前のインターフェース4つを用意し、すべてを「Calc」が実装することにします。

(Main.java)

 

これで四則演算ができるCalcクラスができました。

この時、例えば、足し算だけ行いたい時はどうするかというと、「add関数だけを呼び出せばいいのでは?」と思うかもしれませんが、それだと役割が明確になっていません。

なのでこの場合は、Add型の変数を作るのが正解です。

(Main.java)

このように、複数の機能が付加されたクラスがあることで、それぞれのインターフェースごとにクラスを作成する必要性がなくなり、コードを短くすることができます。

また、Add型を作成することで、Addインターフェース内で宣言された関数しか使えないようになり、役割が明確になり、保守性が向上します。

ちなみに、インスタンス化の時に「new Add()」のような記述方法はできないので注意です。

これは抽象クラスにも同じことが言えます。

まとめ

・抽象クラスは共通の概念の元にあるクラスによって拡張される。

・インターフェースを用いることにより、複数の機能を付加することができる。(複数のクラスを拡張(extends)することはできない。

・1つの機能だけ欲しい場合は、インターフェース型で宣言する。そうすることによって役割が明確になり、保守性が向上する。

関連

・保守性に関して

【保守性とは】Javaで「private」を使うメリット保守性のあるプログラム まずは保守性のあるプログラムを例として組んでいきます。 (Main.java) class Test ...
ABOUT ME
IT系だんし
プログラミングが大好きな人。 趣味でゲームやツール製作をしながら、プログラミング記事を書き続けています。