ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
ポリモーフィズムとは
「多態性」「多様性」と訳される OOP の中心概念。同じ操作 (メソッド呼び出し) でも、対象の型によって異なる挙動になる性質。Java / PHP / Python など多くの言語で「オーバーライド」+「上位型での参照」で実現する。
古典例: 動物クラス
// 親クラス (抽象)
public abstract class Animal {
private String name;
public Animal(String name) { this.name = name; }
public String getName() { return name; }
public abstract String bark(); // サブクラスでオーバーライド
}
// 犬
public class Dog extends Animal {
public Dog(String name) { super(name); }
@Override
public String bark() { return "ワン!"; }
}
// 猫
public class Cat extends Animal {
public Cat(String name) { super(name); }
@Override
public String bark() { return "ニャー"; }
}
// 牛
public class Cow extends Animal {
public Cow(String name) { super(name); }
@Override
public String bark() { return "モー"; }
}
ポリモーフィズムが効くシーン
// ✅ Animal 型のリストに犬・猫・牛を混在させる
List animals = new ArrayList<>();
animals.add(new Dog("ポチ"));
animals.add(new Cat("タマ"));
animals.add(new Cow("モモ"));
// 同じループで各々の鳴き声が出る
for (Animal a : animals) {
System.out.println(a.getName() + ": " + a.bark());
}
// → ポチ: ワン!
// タマ: ニャー
// モモ: モー
// 新しい動物 (Sheep) を追加してもループは無修正!
animals.add(new Sheep("ふわ")); // → ふわ: メェー
ポリモーフィズムが無い世界 (反面教師)
// ❌ ポリモーフィズム未使用: instanceof で分岐
public String bark(Object animal) {
if (animal instanceof Dog) {
return "ワン!";
} else if (animal instanceof Cat) {
return "ニャー";
} else if (animal instanceof Cow) {
return "モー";
}
// 動物が増えるたびに if が増える → OCP 違反
return "...";
}
// ✅ ポリモーフィズム使用: 呼ぶだけ
public String bark(Animal animal) {
return animal.bark(); // 1 行で済む
}
図形クラスでの例
public abstract class Shape {
public abstract double area();
public abstract double perimeter();
}
public class Circle extends Shape {
private double radius;
public Circle(double r) { this.radius = r; }
public double area() { return Math.PI * radius * radius; }
public double perimeter() { return 2 * Math.PI * radius; }
}
public class Rectangle extends Shape {
private double width, height;
public Rectangle(double w, double h) { this.width = w; this.height = h; }
public double area() { return width * height; }
public double perimeter() { return 2 * (width + height); }
}
public class Triangle extends Shape {
private double a, b, c;
public Triangle(double a, double b, double c) { this.a=a; this.b=b; this.c=c; }
public double area() {
double s = (a + b + c) / 2.0;
return Math.sqrt(s * (s-a) * (s-b) * (s-c));
}
public double perimeter() { return a + b + c; }
}
// 利用
List shapes = List.of(
new Circle(5),
new Rectangle(3, 4),
new Triangle(3, 4, 5)
);
double totalArea = shapes.stream()
.mapToDouble(Shape::area)
.sum();
ファクトリパターンとの組み合わせ
// 文字列から動物を生成
public class AnimalFactory {
public static Animal create(String kind, String name) {
return switch (kind) {
case "dog" -> new Dog(name);
case "cat" -> new Cat(name);
case "cow" -> new Cow(name);
default -> throw new IllegalArgumentException(kind);
};
}
}
// 利用
String[] kinds = { "dog", "cat", "cow" };
List animals = Arrays.stream(kinds)
.map(k -> AnimalFactory.create(k, "?"))
.toList();
animals.forEach(a -> System.out.println(a.bark()));
Strategy パターン (戦略パターン)
「アルゴリズムを差し替え可能にする」古典的なポリモーフィズム応用:
// 並び替え戦略
public interface SortStrategy {
List sort(List list);
}
public class BubbleSort> implements SortStrategy {
public List sort(List list) { /* O(n^2) */ return ...; }
}
public class QuickSort> implements SortStrategy {
public List sort(List list) { /* O(n log n) */ return ...; }
}
public class MergeSort> implements SortStrategy {
public List sort(List list) { /* 安定 */ return ...; }
}
// 利用側はインターフェースだけ知っている
public class Sorter {
private SortStrategy strategy;
public Sorter(SortStrategy s) { this.strategy = s; }
public List doSort(List list) { return strategy.sort(list); }
}
new Sorter<>(new QuickSort<>()).doSort(myList);
new Sorter<>(new MergeSort<>()).doSort(myList);
Template Method パターン
共通の流れだけ親クラスに書き、差分はサブクラスで上書き:
public abstract class ReportGenerator {
// テンプレートメソッド (確定アルゴリズム)
public final String generate() {
StringBuilder sb = new StringBuilder();
sb.append(header());
sb.append(body()); // ← サブクラスで実装
sb.append(footer());
return sb.toString();
}
protected String header() { return "===== レポート =====\n"; }
protected String footer() { return "==== ここまで ====\n"; }
protected abstract String body();
}
public class SalesReport extends ReportGenerator {
protected String body() { return "売上: 1,000,000円"; }
}
public class StockReport extends ReportGenerator {
protected String body() { return "在庫: 250 個"; }
}
new SalesReport().generate();
new StockReport().generate();
実務での効果
| シーン | ポリモーフィズム適用例 |
|---|---|
| 支払い方法 | カード / 銀行 / コンビニ → PaymentMethod#pay() |
| 通知 | Email / Slack / Push → Notifier#send() |
| エクスポート | CSV / Excel / PDF → Exporter#export() |
| 認証 | Local / OAuth / SAML → Authenticator#authenticate() |
| キャッシュ | Redis / Memcached / File → Cache#get() |
PHP での例
send($to, $msg);
}
}
notifyAll([
new EmailNotifier(),
new SlackNotifier(),
new LineNotifier(),
], 'user@example.com', '緊急通知');
FAQ
Q: オーバーロード (引数違いの同名メソッド) もポリモーフィズム?
A: 厳密にはアドホック多相と呼ばれ別物。OOP で「ポリモーフィズム」と言えば通常はオーバーライドによるサブタイプ多相を指す。
Q: ポリモーフィズムを使うとパフォーマンスが落ちる?
A: 仮想メソッド呼び出しのコストは現代の JIT で誤差レベル。可読性・保守性のメリットが圧倒的に勝る。
Q: 関数型言語のポリモーフィズム?
A: パラメトリック多相 (ジェネリクス) + 型クラス (Haskell) / 高階関数で実現。OOP のサブタイプ多相とは別系統。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?