Java初心者必見!インタフェースと依存性注入をかんたん解説
こんにちは。ゆうせいです。
今回は、Javaの学習を始めたばかりの新人エンジニアに向けて、「インタフェース」と「依存性注入(Dependency Injection)」という2つの重要な概念をやさしく解説していきます。
いきなりカタカナが多くて少し構えてしまうかもしれませんが、大丈夫です。例え話をまじえながら、実践的な理解につながるように丁寧に説明します!
インタフェースとは?~契約書のようなもの~
インタフェースの基本的な考え方
Javaにおける「インタフェース(interface)」は、一言で言えば「メソッドの仕様だけを定めた設計図」です。
もう少しかみ砕くと、「このクラスはこういう機能を持っているよ!」と約束(契約)するための仕組みなんです。
たとえば、「プリンタ」というクラスを作る場合、「印刷する(print)」という機能を持っているとしましょう。これをインタフェースで定義すると以下のようになります。
public interface Printer {
void print(String message);
}
このインタフェースを「契約書」だと考えてください。この契約書にサインしたクラスは、必ずprint()
というメソッドを実装しなければなりません。
インタフェースの実装例
public class InkjetPrinter implements Printer {
public void print(String message) {
System.out.println("インクジェット印刷: " + message);
}
}
public class LaserPrinter implements Printer {
public void print(String message) {
System.out.println("レーザー印刷: " + message);
}
}
このように、インタフェースによって「使い方を統一」しながら、中身の処理はクラスごとに自由にできます。
依存性注入とは?~電池を取り替えられる懐中電灯のようなもの~
依存性とは?
「依存性」とは、あるクラスが別のクラスに頼っている関係のことです。
たとえば、DocumentPrinter
というクラスがあって、Printer
に依存している場合:
public class DocumentPrinter {
private Printer printer;
public DocumentPrinter() {
this.printer = new InkjetPrinter(); // ここで依存してしまっている!
}
public void printDocument(String text) {
printer.print(text);
}
}
このようにコードの中でnew
してしまうと、他のPrinter
に切り替えたくなったときに修正が大変です。
依存性注入(Dependency Injection, 略してDI)とは?
依存するオブジェクトを外から渡す(注入する)ことで、コードの柔軟性を高める手法が「依存性注入」です。
public class DocumentPrinter {
private Printer printer;
// 依存性を注入するコンストラクタ
public DocumentPrinter(Printer printer) {
this.printer = printer;
}
public void printDocument(String text) {
printer.print(text);
}
}
これでDocumentPrinter
は、InkjetPrinter
でもLaserPrinter
でも、どんなPrinterでも対応できるようになります。
図で理解しよう!
+------------------+ +--------------------+
| DocumentPrinter | -----> | Printer (interface) |
+------------------+ +--------------------+
^
|
+----------------+----------------+
| |
+-------------------+ +---------------------+
| InkjetPrinter | | LaserPrinter |
+-------------------+ +---------------------+
このように、DocumentPrinter
はどのプリンタにも依存できる、拡張性の高い設計になっています。
なぜインタフェースとDIが大事なのか?
メリット
メリット | 内容 |
---|---|
柔軟性 | 仕様を変えずに中身の実装を変更できる |
テストしやすい | テスト用のダミー(モック)を注入できる |
拡張しやすい | 新しい機能を追加しても既存コードに影響が少ない |
デメリット(注意点)
デメリット | 内容 |
---|---|
学習コスト | 最初は仕組みが少し難しいと感じることも |
実装が冗長 | 小さいプロジェクトではオーバースペックになりやすい |
例え話でイメージしよう!
プリンタを家電製品、DocumentPrinter
をそれを操作する人と考えてみましょう。
- インタフェース: 「電源ボタン」や「印刷ボタン」はどのメーカーも共通。
- 実装クラス: メーカー(CanonやEpson)によって、出力の質や速さは違う。
- 依存性注入: あなたの部屋にあるプリンタを「差し替え可能」にする仕組み。
つまり、操作方法は変わらないけど、中身は自由に変えられる。 これが設計として非常に重要なんです!
よくある質問
Q. インタフェースと抽象クラスってどう違うの?
A. 抽象クラス(abstract class)は共通のコード(実装)を持てる点がインタフェースと違います。インタフェースは仕様だけ定義して、実装は一切持ちません。
Q. 依存性注入はどうやって実現するの?
A. 手動でコンストラクタに渡す方法(今回紹介したもの)もあれば、Springなどのフレームワークを使う方法もあります。
今後の学習の指針
次のステップとしては、以下の内容を学んでみましょう!
- Javaの抽象クラスとインタフェースの比較
- Spring Frameworkにおける依存性注入(DIコンテナ)
- テスト駆動開発(TDD)とモックの使い方
- SOLID原則(特に「依存性逆転の原則」)
ゆっくりで大丈夫です。まずは、「インタフェースは契約、DIは部品の差し替え」とイメージできれば上出来です!
何か分からないところがあったら、気軽に聞いてくださいね。
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。