1. Circle(2) と Square(3) の合計は 4 + 9 = 13
  2. Circle(5) と Square(1) の合計は 25 + 1 = 26 (固定値で通せない別パターン)
  3. Circle(1) と Square(0) のように一方が 0 の端境ケースでも area() が正しく合計される
コース一覧
Java 中級:コレクション・Stream・例外処理
ポリモーフィズムを活かす

Java 中級:コレクション・Stream・例外処理

コレクション、ジェネリクス、例外処理、Stream API、関数型インターフェース、日付処理、ファイル I/O、継承など Java の中級トピックを実践的に学べるコースです。Java の基礎文法とオブジェクト指向を理解している学習者を対象に、現場の Java コードを読み書きするための知識を補強します。約 16 時間 (1 日 30 分 × 32 日) で 64 レッスンを修了でき、修了後は Spring Boot や業務システム開発に必要な Java 力が身につきます。

1
コレクション基礎
01. ArrayList を使う5分
02. List を走査する5分
03. 要素の削除と検索5分
04. HashMap の基本5分
05. Map を走査する5分
06. Set で重複を排除5分
07. Collections クラスの便利メソッド5分
08. コレクション基礎 まとめクイズ5分
2
ジェネリクス
01. ジェネリッククラスを作る5分
02. ジェネリックメソッド5分
03. 境界型パラメータ5分
04. ワイルドカード ?5分
05. Pair<K,V> を作る5分
06. ジェネリクス まとめクイズ5分
3
例外処理
01. try-catch で例外をつかむ5分
02. 複数の catch ブロック5分
03. throws と例外の伝播5分
04. 独自の例外を作る5分
05. try-with-resources5分
06. finally ブロック5分
07. 例外処理 まとめクイズ5分
4
Stream API
01. Stream を作る5分
02. filter で絞り込む5分
03. map で変換する5分
04. reduce で集約する5分
05. collect で集める5分
06. sorted で並び替え5分
07. distinct で重複排除5分
08. limit と skip5分
09. 並列ストリーム5分
10. Stream API まとめクイズ5分
5
関数型インターフェース
01. ラムダ式の基本5分
02. メソッド参照 ::5分
03. Function インターフェース5分
04. Predicate インターフェース5分
05. Consumer と Supplier5分
06. BiFunction と 2 引数の関数5分
07. 関数型インターフェース まとめクイズ5分
6
文字列操作
01. String.format で書式化5分
02. StringBuilder で連結5分
03. 正規表現の基本5分
04. split と join5分
05. 文字列操作 まとめクイズ5分
7
日付と時刻
01. LocalDate で日付を扱う5分
02. LocalDateTime で時刻も扱う5分
03. Duration で時間差を計算5分
04. 日付の書式化とパース5分
05. 日付の加減算5分
06. 日付と時刻 まとめクイズ5分
8
ファイル I/O
01. Files でファイルに書き込む5分
02. ファイルを行単位で読む5分
03. Path でファイルパスを扱う5分
04. BufferedReader と Stream API5分
05. ファイルの存在確認と削除5分
06. ファイル I/O まとめクイズ5分
9
継承とポリモーフィズム
01. extends で継承する5分
02. super で親を呼ぶ5分
03. メソッドのオーバーライド5分
04. abstract で抽象クラス5分
05. interface で契約を定義5分
06. default メソッド5分
07. instanceof と型パターン5分
08. ポリモーフィズムを活かす5分
09. 継承とポリモーフィズム まとめクイズ5分

ポリモーフィズムを活かす

種類が 1 つ増えるたびに、if を 1 本足している

通知をまとめて送る処理を、種類ごとの分岐で書いたとします。

Java

for (Object n : notifications) { if (n instanceof MailNotification m) { m.sendMail(); } else if (n instanceof PushNotification p) { p.sendPush(); } }

SMS 通知を足したくなったら、この if に 1 本足します。同じような分岐が別の場所にもあれば、そこも全部です。種類が増えるたびに直すのは、通知クラスではなく 呼ぶ側 なのが厄介なところです。

親の型で受けて、同じ 1 行で呼ぶ

親に共通のメソッド名を決めておき、子がそれぞれ中身を書きます。呼ぶ側は親の型でしか受け取りません。

Java

abstract class Notification { public abstract String send(); } class MailNotification extends Notification { @Override public String send() { return "メールを送信しました"; } } class PushNotification extends Notification { @Override public String send() { return "プッシュを送信しました"; } }

Notification n = new MailNotification(); のように、左を親の型・右を子の型にして代入できます。これを アップキャスト と呼び、(Notification) のような書き足しは要りません。

そのうえで n.send() と呼ぶと、変数の型は Notification なのに、実際に動くのは MailNotification の send() です。Java が実行時にインスタンスの本当のクラスを見て呼び先を決めるからで、これが ポリモーフィズム の正体です。

まとめて入れて、1 回のループで回す

要素の型を親にすれば、種類の違う子をひとつのリストに混ぜられます。

Java

List<Notification> list = List.of(new MailNotification(), new PushNotification()); for (Notification n : list) { System.out.println(n.send()); }

ループの中に分岐は 1 つもありません。SMS 通知のクラスを足しても、直すのはリストに入れる場所だけで、このループは触らずに済みます。冒頭の if の連なりが消えた、ということです。

解説

呼ぶ側で instanceof を並べたくなったら、それは「親に置くべきメソッドがまだ無い」という合図です。分岐の中身に共通の名前を付けられないか、先に考えてみてください。

やってみよう

totalArea(int circleR, int squareS) を完成させてください。

  1. Shape を abstract class として宣言し、public abstract int area(); を持たせる
  2. Circle extends Shape の area() は r * r、Square extends Shape の area() は s * s を返す。半径と一辺はコンストラクタで受け取る
  3. totalArea の中で List<Shape> を作り、Circle と Square を 1 つずつ入れる
  4. for-each で取り出して area() を足し合わせ、合計を int で返す

手順 4 のループの中で instanceof を書く必要はありません。Shape として取り出して area() を呼ぶだけで、円なら円の、正方形なら正方形の計算が動きます。List を使うので java.util.List の import を忘れないでください。

要件

  1. Shape を abstract class として宣言し、抽象メソッド public abstract int area(); を持たせること
  2. Circle extends Shape で r * r を返す area()、Square extends Shape で s * s を返す area() を実装すること
  3. Solution.totalArea(int circleR, int squareS) の中で List<Shape> に new Circle(circleR) と new Square(squareS) を入れ、for-each で area() を合計して int で返すこと

入出力例

totalArea(2, 3) → 13 totalArea(5, 1) → 26 totalArea(1, 0) → 1

ヒント

`List.of(new Circle(circleR), new Square(squareS))` を使うと不変リストを 1 行で作れます。`new ArrayList<Shape>()` + `add` でも構いません

`for (Shape shape : shapes) { total += shape.area(); }` のように親型 `Shape` でループを回せば、実体が `Circle` か `Square` かは Java が動的に判定してくれます

`Circle` も `Square` も `area()` を `@Override` する必要があります。`@Override` を付けておくと、シグネチャを間違えたときにコンパイラが教えてくれます

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 継承とポリモーフィズム まとめクイズ

    中級「継承とポリモーフィズム」章の総まとめ。`extends` / `super` / `@Override` / `abstract` / `interface` / `default` / `instanceof` / ポリモーフィズムの使い分けを 4 択で総ざらいする、コース最終クイズ。

  • instanceof と型パターン

    Java の `instanceof` 演算子と、Java 16 以降のパターンマッチングを学び、オブジェクトの実型に応じて分岐するコードを書いてみよう。

  • default メソッド

    Java 8 で導入された interface の default メソッドの使い方と、後方互換性を保ちながら共通実装を提供する仕組みを学び、英語版あいさつメソッドを書いてみよう。

  • interface で契約を定義

    Java の interface を使って「契約」だけを定義し、implements で複数のクラスに同じ振る舞いを約束させる方法を学ぼう。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 処理計算や代入を表す長方形
  • クラスデータと振る舞いを束ねる単位
  • メソッドクラスに属する関数
  • instanceof「このオブジェクトの実際の型は何か」を確認 → 安全に変換
  • 変数データに名前をつけて参照する仕組み
  • インスタンスクラスから生成された実体
  • ポリモーフィズム同名メソッドが型ごとに振る舞いを変える性質
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
main.java
学習モード
エディタを読み込んでいます

メモ

ポリモーフィズムを活かす

⌘S で保存