[Java]インタフェースと抽象クラスの使い方

ソフトウェア開発

Javaの勉強をしていると必ずインタフェースや抽象クラスという言葉が出てきます。単体での使い方や機能は理解できても、いまいち実際の使い道やこれらの使い分けがピンときていませんでした。同様の考えをお持ちの方に向けて今回はインタフェースや抽象クラスの実際の使い方について解説したいと思います。

抽象クラス

抽象クラスというのはクラスの概念を抽象化したものです。サブクラスに実装を任せる(オーバーライド)抽象メソッドを持たせることができ、単独ではインスタンス化することができません。抽象メソッドだけでなく具象メソッドを定義することもできるので、サブクラスの共通処理を抽象クラスにまとめておく使い方もできます。それ以外は通常のクラスと同じ性質になっているので、多重継承も不可です。抽象クラスに共通部分がまとめてあり、サブクラスごとに異なる処理は抽象メソッドになっているはずなので、サブクラスを実装する際はその部分のみを実装すればよいという考え方になります。

インタフェース

抽象クラスと違い、基本的にはフィールドは定数、メソッドは抽象メソッドという制約があります(Java8からデフォルト実装という機能ができましたが、ここでは一旦置いておきます)。抽象クラスと同様、単独ではインスタンス化することはできません。全てが抽象メソッドになるので、実装クラスでは全てのメソッドを実装する必要があります。このような性質上、インタフェースは類似したクラス群の性質を表した定義であると捉えることができます。またクラスとの大きな違いとして、2つ以上のインタフェースを実装することができるようになっています。

共通点と相違点

ここまでをまとめると、抽象クラスとインタフェースでは以下のような共通点と相違点があります。

共通点

  • 抽象メソッドを定義できる
  • 単独でインスタンス化できない

相違点

  • インタフェースは基本的には抽象メソッドであることが前提
  • インタフェースを2つ以上実装したクラスを定義できる

このように見ると、非常に似たような機能を備えている一方で、いくらか異なる性質を持っていることがわかると思います。自分の感覚としては、インタフェースは外部用、抽象クラスは内部用と捉えています。インタフェースは抽象メソッドや定数といったクラス群の定義部分になるので、それらの機能を使用する外部にはそれしか見せず、内部の実装は隠蔽することができます。まさに「インタフェース」という言葉そのものですね。一方で抽象クラスは具象メソッドも定義できるので、クラス群の共通処理をまとめておくことで内部の実装をしやすくする役割があると言えます。

実際の使い方

インタフェースと抽象クラスについて学習していると、どちらか一方を使うイメージで考えがちなのですが、上記のように外部用と内部用という違う役割を持っているので、両方を併用することでよりオブジェクト指向を意識した設計にすることができます。具体的には例えば以下のように、一番上にインタフェースを定義しておき、その実装クラスがあるのですが、その間にサブクラス群の共通処理をまとめた抽象クラスを配置することができます。

public interface ListOperation {
    void add(String name);
    void delete();
}
public abstract class AbstractListOperation implements ListOperation {
    protected List<String> list() {
        //サブクラス用の共通処理
    }
}
public class TotalListOperation extends AbstractListOperation {
    @Override
    public void add(String name) {
        ...
    }
}

インタフェースは外部から見た定義だけを書いていて、内部の処理が変更されても影響を受けることはありません。インタフェースで定義されている抽象メソッドに対して、サブクラスではそれぞれで固有の処理を実装します。そしてサブクラスで共通の処理があれば、具体的な処理は中間の抽象メソッドにまとめておきます。こうすることで外部に対するメリットと内部に対するメリットの両方を生かすことができます。抽象クラスだけでなくインタフェースも併用することで、クラス間の依存関係を弱めたり、テストコードでモックを使いやすくなるといったメリットもあります。個人で開発しているぶんにはあまり意識しなくても問題ありませんが、複数人である程度の規模の開発を行なう際にはどちらも必要な概念になるので、この併用によるメリットを最大限生かして効率的に開発できるようにしましょう。

参考文献

抽象クラスとインタフェースという基本的な概念についてはこちらのやさしいシリーズを参考にさせていただきました。


これらの概念だけでなく、Java全般の基礎概念について文字通りやさしく解説してあるので初学者にもおすすめです。サンプルコードも理解しやすく、こちらを真似て自分で一度コードを書いてみると理解も深まります。

基礎を学んだ後、実際のアプリケーションに生かすための方法や考え方について踏み込んで書かれているのがこちらの「Java本格入門」になります。


今回のテーマで言えば抽象クラスとインタフェース自体は理解できたけど、具体的な違いや使い方まで踏み込んで解説してくれているので、すぐに実務に生かせる知識を得られます。やさしいシリーズなどで基礎概念を学んだ後、実際の開発に生かせるメソッドを学びたい方には是非おすすめいたします。

まとめ

Javaのインタフェースと抽象クラスについて、その基礎概念だけでなく根本的な違いや使い分け方法について具体的にご説明しました。オブジェクト指向に慣れていないと概念自体がわかりづらいですし、開発におけるメリットも最初はピンとこないと思います。それでもこれらが使えると開発効率も上がり、コード全体の可読性も上がります。そして使いこなせることでオブジェクト指向を使えている実感と共に開発者としてレベルアップできます!是非楽しんでコーディングしてみてください。

以上ご参考になれば幸いです。お読みいただきありがとうございました。

タイトルとURLをコピーしました