ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
継承の基本
// 親クラス (スーパークラス / 基底クラス)
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void sleep() {
System.out.println(name + " is sleeping");
}
}
// 子クラス (サブクラス / 派生クラス)
public class Dog extends Animal {
public Dog(String name) {
super(name); // ★ 親のコンストラクタを呼び出し
}
// 親のメソッドをオーバーライド
@Override
public void sleep() {
System.out.println(name + " (dog) is sleeping like a log");
}
// 子独自のメソッド
public void bark() {
System.out.println(name + " says: Woof!");
}
}
// 利用
Dog d = new Dog("Pochi");
d.sleep(); // オーバーライドされた版
d.bark(); // 子独自
// 親型変数に子を入れる (ポリモーフィズム)
Animal a = new Dog("Hachi");
a.sleep(); // 動的ディスパッチで Dog の sleep が呼ばれる
// a.bark(); // ★ コンパイルエラー (Animal 型では bark を知らない)
extends と super
| キーワード | 意味 |
|---|---|
extends | 子クラスが親を継承することを宣言 |
super(...) | 親のコンストラクタ呼び出し (コンストラクタ最初の文) |
super.method() | 親のメソッドを呼び出し |
super.field | 親のフィールドを参照 |
@Override | オーバーライド宣言 (任意だが付けるべき) |
final class | 継承禁止 |
final method | オーバーライド禁止 |
Constructor Chaining (親 → 子 の順で実行)
class A {
public A() { System.out.println("A()"); }
}
class B extends A {
public B() {
// super(); ← ★ 暗黙で挿入される (引数なしコンストラクタ呼び出し)
System.out.println("B()");
}
}
class C extends B {
public C() {
super(); // 明示
System.out.println("C()");
}
}
new C();
// 出力:
// A()
// B()
// C()
// 親に引数なしコンストラクタが無いと
class X {
public X(int n) { }
}
class Y extends X {
public Y() {
// ★ コンパイルエラー (X の引数なしコンストラクタが無い)
// → 明示的に super(0); 等が必要
}
}
IS-A 関係 (継承の判断基準)
「子は親の一種である」が言えるときだけ継承を使います:
- Dog は Animal ✅
- Manager は Employee ✅
- Square は Rectangle … ✗ (有名な反例: 高さと幅を独立変更できない)
- Stack は ArrayList … ✗ (Stack に
get(0)が露出するのは設計ミス → Composition 推奨)
Liskov 置換原則 (LSP)
子は親の代わりに使えなければならない。つまり、親型変数に子インスタンスを入れても期待通り動くこと:
// 古典的反例 (Square extends Rectangle)
class Rectangle {
protected int w, h;
public void setWidth(int w) { this.w = w; }
public void setHeight(int h) { this.h = h; }
public int area() { return w * h; }
}
class Square extends Rectangle {
// 正方形なので幅と高さを連動
@Override
public void setWidth(int w) { this.w = w; this.h = w; }
@Override
public void setHeight(int h) { this.w = h; this.h = h; }
}
void test(Rectangle r) {
r.setWidth(5);
r.setHeight(3);
assert r.area() == 15; // ★ Square だと 9 になり契約違反
}
// → Square IS NOT a Rectangle (LSP 違反)
ダイヤモンド継承問題と Java の解決策
C++ のような多重継承では「同じ親を 2 つ持つ子」で同じメソッドのどちらが呼ばれるか曖昧になります (ダイヤモンド問題)。Java は class の多重継承を禁止し、代わりに interface (および default メソッド) を用意:
interface Flyable {
default void move() { System.out.println("Flying"); }
}
interface Swimmable {
default void move() { System.out.println("Swimming"); }
}
class Duck implements Flyable, Swimmable {
// ★ どちらの default を使うか曖昧 → コンパイルエラー
@Override
public void move() {
Flyable.super.move(); // 明示で解決
}
}
protected アクセス
public class Animal {
protected String name; // 子からアクセス可
private int secretId; // 子からも見えない
protected void onSleep() { } // フック (子が拡張用)
}
public class Dog extends Animal {
public void greet() {
System.out.println(name); // ✅ protected フィールドにアクセス
// System.out.println(secretId); // ★ NG (private)
}
}
final class で継承禁止
// String, Integer, LocalDate などは final
public final class Coordinate {
private final double x, y;
// ...
}
// public class GeoCoordinate extends Coordinate { } // ★ コンパイルエラー
// 用途:
// - イミュータブル (不変) を保証したい
// - セキュリティ上、サブクラスで挙動を変えられたくない
// - 設計者がサブクラス対応していない
Composition over Inheritance (★ 重要原則)
「is-a」ではなく「has-a」が成り立つなら、継承ではなく Composition (持つ) を使う方が柔軟。
// ❌ 継承
public class CountingList<E> extends ArrayList<E> {
private int addCount = 0;
@Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
// ★ ArrayList.addAll が内部で add を呼ぶ実装だと
// addCount が 2 倍カウントされる (実装に依存するバグ)
}
}
// ✅ Composition
public class CountingList<E> {
private final List<E> inner = new ArrayList<>();
private int addCount = 0;
public boolean add(E e) {
addCount++;
return inner.add(e);
}
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return inner.addAll(c);
}
}
言語別比較
| 言語 | 継承記法 | 多重継承 |
|---|---|---|
| Java | class B extends A | 不可 (interface 複数 OK) |
| PHP | class B extends A | 不可 (trait あり) |
| C# | class B : A | 不可 (interface 複数 OK) |
| Python | class B(A): | ★ 可 (MRO で解決) |
| C++ | class B : public A | ★ 可 (virtual 継承) |
| Ruby | class B < A | 不可 (Mixin で実質可) |
Mixin / trait
多重継承の代わりに、PHP の trait や Ruby / Python の Mixin で「振る舞いを横断的に追加」する仕組み:
trait Loggable {
public function log(string $msg): void {
error_log(static::class . ": $msg");
}
}
class UserService {
use Loggable; // trait を取り込む
}
(new UserService())->log("created");
FAQ
Q: 継承と Composition どちらを使うべき?
A: 迷ったら Composition。IS-A が自然に成り立つ場合のみ継承。
Q: extends と implements の違い
A: extends はクラス継承 (1 つだけ)、implements はインターフェース実装 (複数可)。クラスは extends X implements Y, Z のように両方使える。
Q: 親クラスを変更すると子に影響が出る
A: 継承の宿命 (壊れやすい基底クラス問題)。public API を慎重に設計し、安易な protected フィールド公開は避ける。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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アノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?