ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
インターフェースとは
クラスが「こういうメソッドを持っていますよ」と外部に約束するための仕組み。実装は持たず、メソッドのシグネチャ (名前 + 引数 + 戻り値) だけを宣言する。実装は implements 側のクラスが書く。
// インターフェース定義
public interface Drawable {
void draw(); // 抽象メソッド (public abstract)
int getArea();
}
// 実装クラス1
public class Circle implements Drawable {
private int radius;
public Circle(int r) { this.radius = r; }
@Override
public void draw() {
System.out.println("○ 円を描画");
}
@Override
public int getArea() {
return (int) (Math.PI * radius * radius);
}
}
// 実装クラス2
public class Square implements Drawable {
private int side;
public Square(int s) { this.side = s; }
@Override
public void draw() {
System.out.println("□ 四角を描画");
}
@Override
public int getArea() {
return side * side;
}
}
なぜインターフェースが必要か(4 つのメリット)
1. 差し替え可能 (DIP: 依存性逆転原則)
呼び出し側は実装クラスではなくインターフェースに依存することで、後から実装を差し替えられる:
// ❌ 直接 MySQLRepository に依存 (実装に依存)
public class UserService {
private MySQLUserRepository repo = new MySQLUserRepository();
// → DB を Postgres に変えたら UserService も修正
}
// ✅ インターフェースに依存
public interface UserRepository {
User findById(long id);
void save(User u);
}
public class MySQLUserRepository implements UserRepository { ... }
public class PostgresUserRepository implements UserRepository { ... }
public class UserService {
private final UserRepository repo; // 抽象に依存
public UserService(UserRepository repo) {
this.repo = repo; // コンストラクタ注入
}
}
// 利用側で実装を選ぶ
UserService svc = new UserService(new MySQLUserRepository());
UserService svc = new UserService(new PostgresUserRepository());
2. テスト時にモックに差し替え
// テスト用のフェイク実装
public class FakeUserRepository implements UserRepository {
private Map store = new HashMap<>();
public User findById(long id) { return store.get(id); }
public void save(User u) { store.put(u.getId(), u); }
}
// テストコード
@Test
void testRegisterUser() {
UserRepository repo = new FakeUserRepository();
UserService svc = new UserService(repo);
svc.register(new User("taro"));
assertEquals("taro", repo.findById(1L).getName());
// DB なしでテストが回せる
}
3. ポリモーフィズム (多態性)
// 異なるクラスを同じ List で扱える
List shapes = new ArrayList<>();
shapes.add(new Circle(5));
shapes.add(new Square(3));
shapes.add(new Circle(10));
// instanceof やキャスト不要!
for (Drawable s : shapes) {
s.draw(); // ○ 円を描画 / □ 四角を描画
System.out.println(s.getArea());
}
// 合計面積
int total = shapes.stream()
.mapToInt(Drawable::getArea)
.sum();
4. 戦略パターン (Strategy)
// 支払い方法のインターフェース
public interface PaymentStrategy {
void pay(int amount);
}
// 各実装
public class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) { /* Stripe API 呼び出し */ }
}
public class BankTransferPayment implements PaymentStrategy {
public void pay(int amount) { /* 銀行 API 呼び出し */ }
}
public class PayPalPayment implements PaymentStrategy {
public void pay(int amount) { /* PayPal API 呼び出し */ }
}
// 利用側は実装を知らなくていい
public class CheckoutService {
public void checkout(PaymentStrategy method, int total) {
method.pay(total); // ← 実装が何でも動く
}
}
インターフェース vs 抽象クラス
| 項目 | interface | abstract class |
|---|---|---|
| 多重継承 | ◯ implements A, B, C | × 単一継承のみ |
| フィールド | × (定数のみ) | ◯ |
| コンストラクタ | × | ◯ |
| 実装持てる | Java 8+ default メソッド | ◯ |
| 用途 | 「できること」(can-do) | 「共通実装」(is-a) |
判断基準: 共通実装を持ちたいなら抽象クラス、多種から同じ型として扱いたいならインターフェース。両者の組み合わせも有効 (テンプレートメソッドパターン)。
PHP のインターフェース
path, "[$level] $message\n", FILE_APPEND);
}
}
class SlackLogger implements Logger {
public function log(string $level, string $message): void {
// Slack Webhook へ POST
}
}
// 利用
function notify(Logger $logger, string $msg): void {
$logger->log('ERROR', $msg);
}
notify(new FileLogger('/var/log/app.log'), '失敗');
notify(new SlackLogger(), '失敗');
Java 8+ の default メソッド
public interface Animal {
String getName();
// デフォルト実装を持てる
default String greet() {
return "I am " + getName();
}
}
public class Dog implements Animal {
public String getName() { return "Pochi"; }
// greet() は実装不要
}
new Dog().greet(); // → "I am Pochi"
マーカーインターフェース
メソッドを持たない、「型のラベル」として使うインターフェース。java.io.Serializable など:
public interface Serializable {} // メソッド無し
public class User implements Serializable {
private String name;
}
// 利用側で型チェック
if (obj instanceof Serializable) {
// シリアライズ可能と判断
}
FAQ
Q: メソッド 1 つしか無いならクラスでよい?
A: テストで差し替えたい / 戦略パターンで切り替えたい場合はインターフェースに。Java 8+ ならFunction や Supplier 等の関数型インターフェースで代用可。
Q: インターフェースに定数を書いていい?
A: 書けるが避けるべき (定数インターフェースアンチパターン)。定数は final class Constants や enum に。
Q: 実装クラスの方が便利ではないか?
A: コードの規模が大きくなると「修正の影響範囲が読めない」「テストが書きにくい」「実装を差し替えたい」が必ず出てきます。インターフェースは将来の自分への投資です。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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
コメントを削除してもよろしいでしょうか?