ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
抽象クラスとは
抽象クラス (abstract class) は、そのままではインスタンス化できないクラスです。サブクラスで継承して具象化することを前提に作られ、共通フィールドと実装を提供しつつ、特定のメソッドの実装をサブクラスに強制します。
OOP では「テンプレートを作り、変動する部分だけ子クラスに任せたい」という場面が頻出します。これを言語仕様レベルで強制するのが抽象クラスの役割です。
基本構文 (Java)
// 抽象クラスの定義
public abstract class Shape {
protected String name;
public Shape(String name) {
this.name = name;
}
// 実装済みメソッド (サブクラスで共通利用)
public String describe() {
return name + " の面積は " + area();
}
// 抽象メソッド (サブクラスで実装必須)
public abstract double area();
}
// サブクラスは abstract メソッドを必ず override
public class Circle extends Shape {
private double r;
public Circle(double r) {
super("円");
this.r = r;
}
@Override
public double area() {
return Math.PI * r * r;
}
}
// 利用
Shape s = new Shape("X"); // ← コンパイルエラー: abstract をインスタンス化不可
Shape c = new Circle(3.0); // OK: 具象サブクラスはインスタンス化可能
System.out.println(c.describe()); // → 円 の面積は 28.27...
PHP / C# での書き方
name = $name;
}
public function describe(): string {
return "{$this->name} の面積は " . $this->area();
}
// 抽象メソッド
abstract public function area(): float;
}
class Circle extends Shape {
public function __construct(private float $r) {
parent::__construct("円");
}
public function area(): float {
return M_PI * $this->r ** 2;
}
}
$c = new Circle(3.0);
echo $c->describe();// C# の抽象クラス
public abstract class Shape {
protected string Name;
protected Shape(string name) => Name = name;
public string Describe() => $"{Name} の面積は {Area()}";
// C# は abstract キーワードで宣言
public abstract double Area();
}
public class Circle : Shape {
private double r;
public Circle(double r) : base("円") { this.r = r; }
// override キーワード必須
public override double Area() => Math.PI * r * r;
}
interface との違い
| 項目 | 抽象クラス | interface |
|---|---|---|
| インスタンス化 | 不可 | 不可 |
| フィールド | 持てる(状態あり) | 定数のみ(Java)/ 通常持てない |
| 実装済みメソッド | 持てる | Java 8+ default で可 / C# 8+ default で可 |
| コンストラクタ | 持てる(サブクラスから super 呼出) | 持てない |
| 多重継承 | ×(単一継承のみ) | ○(複数 implements 可) |
| 用途 | 「is-a」+ 共通実装の共有 | 「振る舞い契約」だけを規定 |
原則は「共通状態や処理を共有したい → 抽象クラス / 異なる継承ツリーに同じ契約を貼りたい → interface」です。
Java 8+ default メソッドで interface が抽象クラスに迫る
// Java 8+: interface に default 実装を持てる
public interface Greetable {
String name();
// default メソッド: 実装を持つ
default String greet() {
return "Hello, " + name();
}
}
public class User implements Greetable {
@Override public String name() { return "Alice"; }
}
new User().greet(); // → Hello, Alice
これにより「実装の共有」も interface でできるようになりましたが、状態(フィールド)を持てない点が決定的に異なります。状態が必要なら抽象クラス、状態不要なら interface です。
Template Method パターンでの活用
抽象クラスの古典的活用が Template Method パターンです。アルゴリズムの骨格を親で定義し、変動部分のみ子に委ねます:
// テンプレート: データ処理パイプラインの骨格
public abstract class DataProcessor {
// 公開メソッド (final にして上書き禁止)
public final void run() {
var data = load();
var processed = process(data);
save(processed);
}
protected abstract List load();
protected abstract List process(List data);
protected abstract void save(List data);
}
// 具象 1: CSV 用
public class CsvProcessor extends DataProcessor {
protected List load() { /* CSV 読み込み */ }
protected List process(List d) { /* 変換 */ }
protected void save(List d) { /* CSV 出力 */ }
}
// 具象 2: JSON 用
public class JsonProcessor extends DataProcessor {
/* 同じ run() が JSON 用処理を実行する */
}
ストラテジーパターンとの比較
振る舞いの差し替えだけが目的ならストラテジー(interface 経由)のほうが疎結合です。状態・共通処理を共有したいなら抽象クラスを選びます:
- ストラテジー: 振る舞い (Strategy interface) を Context にコンポジションする → 実行時切替が容易
- Template Method: 継承で固定 → コンパイル時に決まる、コードの重複削減に強い
final と abstract の対比
| 修飾子 | クラス | メソッド | 意図 |
|---|---|---|---|
abstract | インスタンス化不可、継承前提 | 実装なし、サブクラスで実装必須 | 「継承して使え」 |
final | 継承不可 | override 不可 | 「これ以上変えるな」 |
同一メソッドに abstract と final を同時に付けるのは矛盾なのでコンパイルエラーになります。
使うべき場面 / 避けるべき場面
- 使うべき: 共通フィールド・共通処理を持ちつつ、一部メソッドだけサブクラスごとに変えたい
- 使うべき: Template Method / Factory Method パターン適用時
- 避ける: 単一の「振る舞い契約」しか必要ないとき → interface のほうが疎結合
- 避ける: ライブラリ公開 API の上位型 → 抽象クラスは進化させづらい(メソッド追加でサブクラス全滅)。interface + default のほうが安全
FAQ
Q: 抽象クラスにコンストラクタって意味あるの?
A: あります。サブクラスから super(...) で呼び出され、共通フィールドの初期化に使われます。
Q: abstract メソッドのない abstract クラスは作れる?
A: 作れます。「インスタンス化させたくない基底クラス」として使えます。
Q: PHP / Java / C# 以外でも同じ?
A: Kotlin・Scala・TypeScript も abstract キーワードあり。Python は abc.ABC + @abstractmethod で同等を実現します。Go は abstract クラスを持たず interface のみで設計します。
Q: 多重継承したいときは?
A: 多くの言語で抽象クラスは単一継承のみ。複数の役割を継承したい場合は interface を組み合わせるのが定石です(Java では extends AbstractBase implements I1, I2)。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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
コメントを削除してもよろしいでしょうか?