11.

Java クラス完全ガイド

編集
この記事の要点
  • クラス = フィールド (状態) + メソッド (振る舞い) + コンストラクタをひとまとめにした設計図
  • 構文: [修飾子] class クラス名 { ... }。命名規則は PascalCase
  • 修飾子: public/private/protected/(パッケージプライベート) + static/final/abstract
  • 内部クラス 4 種: static nested / inner / anonymous / local
  • モダン Java: record (Java 14+ 不変データ) と sealed (Java 17+ 継承制限)

クラスの基本構文

public class User {
    // フィールド (状態)
    private String name;
    private int age;

    // コンストラクタ
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // メソッド (振る舞い)
    public String getName() { return name; }
    public int getAge() { return age; }

    public void birthday() {
        age++;
    }

    @Override
    public String toString() {
        return "User{name=" + name + ", age=" + age + "}";
    }
}

// 使う側
User u = new User("Alice", 30);
u.birthday();
System.out.println(u);   // User{name=Alice, age=31}

アクセス修飾子

修飾子同じクラス同じパッケージサブクラスその他
publicOOOO
protectedOOOX
(無指定 = package-private)OOXX
privateOXXX

カプセル化の基本: フィールドは private、必要なものだけ public な getter/setter で公開します。

static / final / abstract

public class MathUtil {
    // static フィールド = クラス共有の値 (定数)
    public static final double PI = 3.14159265;

    // static メソッド = インスタンス不要で呼べる
    public static double square(double x) {
        return x * x;
    }
}

// インスタンス化せず呼ぶ
double area = MathUtil.PI * MathUtil.square(5);

// abstract = 抽象クラス (インスタンス化できない)
public abstract class Animal {
    abstract String sound();
    public void introduce() {
        System.out.println("I say " + sound());
    }
}

// 継承して実装
public class Dog extends Animal {
    String sound() { return "Woof"; }
}

// final クラス = 継承不可 (String, Integer 等)
public final class Constants { ... }

コンストラクタとオーバーロード

public class User {
    private String name;
    private int age;

    // デフォルトコンストラクタ (引数なし)
    public User() {
        this("(Unknown)", 0);   // this() で他コンストラクタを呼ぶ
    }

    public User(String name) {
        this(name, 0);
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 全て有効
new User();
new User("Alice");
new User("Alice", 30);

内部クラス 4 種

種類定義場所外側インスタンス参照用途
static nestedクラス内不可外側と関連するが独立して使う
innerクラス内 (非 static)外側のフィールド使う補助
localメソッド内そのメソッド内専用
anonymousその場で new1 回限りのインターフェース実装
public class Outer {
    private int x = 10;

    // 1. static nested
    static class StaticNested {
        void hi() { System.out.println("static nested"); }
    }

    // 2. inner
    class Inner {
        void hi() { System.out.println("inner, x=" + x); }   // 外側 x 参照可
    }

    void method() {
        // 3. local
        class Local { void hi() { System.out.println("local"); } }
        new Local().hi();

        // 4. anonymous
        Runnable r = new Runnable() {
            public void run() { System.out.println("anon"); }
        };
        r.run();

        // モダン Java は Lambda で代替
        Runnable r2 = () -> System.out.println("lambda");
    }
}

new Outer.StaticNested().hi();        // static は Outer 不要
new Outer().new Inner().hi();         // inner は Outer インスタンス経由

record (Java 14+)

// 不変データクラスを 1 行で
public record User(String name, int age) {}

// 自動生成されるもの:
// - private final フィールド name, age
// - コンストラクタ User(String, int)
// - アクセサ name(), age()
// - equals / hashCode / toString

User u = new User("Alice", 30);
System.out.println(u.name());           // Alice
System.out.println(u);                  // User[name=Alice, age=30]

// カスタムロジックを追加
public record User(String name, int age) {
    public User {                         // コンパクトコンストラクタ
        if (age < 0) throw new IllegalArgumentException();
    }
    public String greeting() {
        return "Hi, " + name;
    }
}

sealed (Java 17+)

// permits で継承可能なクラスを限定
public sealed interface Shape
    permits Circle, Square, Triangle {}

public record Circle(double r) implements Shape {}
public record Square(double side) implements Shape {}
public record Triangle(double a, double b, double c) implements Shape {}

// switch パターンマッチング (Java 21+) で網羅性チェック
double area(Shape s) {
    return switch (s) {
        case Circle c   -> Math.PI * c.r() * c.r();
        case Square sq  -> sq.side() * sq.side();
        case Triangle t -> 0.5 * t.a() * t.b();
    };  // default 不要、コンパイル時に網羅性検証
}

シングルトンパターン

// 1 つしかインスタンス作らせない
public class Config {
    private static final Config INSTANCE = new Config();
    private Config() { /* 外部から new 禁止 */ }
    public static Config getInstance() { return INSTANCE; }
}

Config c = Config.getInstance();

// ★ enum で書くのが最もシンプル
public enum SingletonEnum {
    INSTANCE;
    public void doWork() { ... }
}
SingletonEnum.INSTANCE.doWork();

JavaBean 規約

  • 引数なしの public コンストラクタを持つ
  • フィールドは private、getter / setter で公開
  • getter は getXxx()、setter は setXxx()。boolean は isXxx()
  • Serializable を実装することが多い

多くのフレームワーク (Spring, JPA, Jackson) が JavaBean 規約を前提に動きます。

コンパイルと実行

# 単一ファイル
javac User.java        # User.class が生成
java User              # main メソッドを実行

# Java 11+ は javac せずに直接実行可能
java User.java

# パッケージ付き
javac -d build src/com/example/User.java
java -cp build com.example.User

FAQ

Q: クラスと interface の使い分けは?
A: 状態を持つなら class、契約 (メソッド一覧) だけならインターフェース。Java 8+ は default メソッドで実装も持てるが、状態 (フィールド) は依然 class のみ。

Q: record と class どちらを使う?
A: 不変データ転送オブジェクト (DTO) は record。状態を変えたり継承したいなら class。

Q: 1 ファイルに複数 public クラスを書ける?
A: 不可。1 ファイル 1 public クラス、ファイル名はクラス名と一致。非 public なら同居可能。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. データ型
  3. 変数
  4. 定数
  5. 配列
  6. コレクション(List,Set,Queue)
  7. Map(連想配列)
  8. 演算子
  9. 条件分岐
  10. 繰り返し制御文
  11. クラス
  12. メソッド
  13. インスタンス化
  14. コンストラクタ
  15. staticキーワード
  16. オーバーロード
  17. 継承
  18. オーバーライド
  19. this
  20. super
  21. パッケージ
  22. アクセス修飾子
  23. 抽象クラス・メソッド
  24. インターフェース
  25. カプセル化
  26. データベース接続
  27. セッション
  28. ファイル入出力
  29. ラムダ式

最近更新/作成されたページ