12.

Java クラスとメソッド完全ガイド — フィールド・修飾子・継承

編集
この記事の要点
  • クラスは「設計図」、オブジェクトはその「実体」。new ClassName() でインスタンス化
  • クラスは フィールド (状態)メソッド (振る舞い) + コンストラクタ を持つ
  • アクセス修飾子: public / protected / package-private / private の 4 段階
  • static はインスタンス不要 (クラス共有)、final は変更/継承禁止、abstract は実装なし
  • Java 14+ record でデータクラスを 1 行で。Java 17+ sealed で継承先を限定

クラスの基本構造

public class User {
    // フィールド (インスタンス変数)
    private String name;
    private int age;

    // クラス変数 (static)
    private static int totalCount = 0;

    // 定数
    public static final int MAX_AGE = 150;

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

    // インスタンスメソッド
    public String greet() {
        return "Hello, I'm " + this.name;
    }

    // static メソッド (インスタンス不要)
    public static int getTotalCount() {
        return totalCount;
    }

    // getter / setter
    public String getName()           { return name; }
    public void setName(String name)  { this.name = name; }
}

// 使用
User u = new User("Taro", 25);
System.out.println(u.greet());            // インスタンスメソッド
System.out.println(User.getTotalCount()); // static メソッド
System.out.println(User.MAX_AGE);          // 定数

アクセス修飾子

修飾子同一クラス同一パッケージ子クラス他パッケージ
public
protected
(なし) package-private
private

原則:

  • フィールドは private (カプセル化) → getter/setter で公開
  • メソッドは最小限の公開 (内部実装は private)
  • クラスは public または package-private (1 ファイル 1 public クラス)

static (クラス変数 / クラスメソッド)

public class Counter {
    private static int count = 0;  // クラス全体で 1 つ

    public static void increment() {  // インスタンス不要
        count++;
    }

    public static int get() {
        return count;
    }
}

Counter.increment();
Counter.increment();
System.out.println(Counter.get());  // 2

// static メソッドからインスタンス変数 / メソッドにアクセスは ★ 不可
public class Bad {
    private int x;            // インスタンス変数

    public static void f() {
        // System.out.println(x);  // ★ コンパイルエラー
    }
}

final (変更禁止 / 継承禁止)

// final 変数: 再代入不可
public final int MAX = 100;

// final メソッド: オーバーライド不可
public final void critical() { ... }

// final クラス: 継承不可
public final class String { ... }   // String, Integer, LocalDate 等

// 引数 final
public void process(final List<String> list) {
    // list = new ArrayList<>();  // ★ NG
    list.add("a");                 // OK (参照先の中身は変えられる)
}

abstract クラス / インターフェース

// abstract クラス: インスタンス化不可、子で実装させる
public abstract class Shape {
    public abstract double area();           // 実装なし
    public void describe() {                 // 実装あり
        System.out.println("Area = " + area());
    }
}

class Circle extends Shape {
    private double r;
    public Circle(double r) { this.r = r; }
    @Override
    public double area() { return Math.PI * r * r; }
}

// interface (Java 8+ default メソッドあり)
public interface Greetable {
    void greet();                                        // 抽象メソッド
    default void hello() { System.out.println("Hi"); }   // default 実装
    static void info() { System.out.println("v1"); }     // static
}

class Hello implements Greetable {
    @Override
    public void greet() { System.out.println("Hello!"); }
}

インナークラス (内部クラス)

public class Outer {
    private int x = 10;

    // 1. インスタンス内部クラス
    public class Inner {
        public int sum() { return x + 1; }   // Outer の x にアクセス可
    }

    // 2. static ネストクラス
    public static class StaticNested {
        public int val = 5;
    }

    // 3. ローカルクラス (メソッド内)
    public void method() {
        class Local {
            public void hi() { System.out.println(x); }
        }
        new Local().hi();
    }

    // 4. 匿名クラス
    public Runnable task = new Runnable() {
        @Override
        public void run() { System.out.println("run"); }
    };
}

// 利用
Outer o = new Outer();
Outer.Inner i = o.new Inner();
Outer.StaticNested s = new Outer.StaticNested();

record (Java 14+) — データクラスを 1 行で

// 旧来 (50 行ぐらいの boilerplate が必要)
public final class Point {
    private final int x;
    private final int y;
    public Point(int x, int y) { this.x = x; this.y = y; }
    public int x() { return x; }
    public int y() { return y; }
    @Override public boolean equals(Object o) { ... }
    @Override public int hashCode() { ... }
    @Override public String toString() { ... }
}

// ✅ record で 1 行
public record Point(int x, int y) {}

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

Point p = new Point(1, 2);
System.out.println(p.x());        // 1
System.out.println(p);            // Point[x=1, y=2]

// メソッド追加も可
public record Money(long amount, String currency) {
    public Money plus(Money other) {
        return new Money(amount + other.amount, currency);
    }
}

sealed クラス (Java 17+)

// 「これらの子のみ許可」と明示
public sealed interface Shape permits Circle, Square, Triangle {}

public final class Circle   implements Shape { ... }
public final class Square   implements Shape { ... }
public final class Triangle implements Shape { ... }
// public class Pentagon implements Shape {} // ★ コンパイルエラー (permits に無い)

// switch でも網羅性チェック可
double area(Shape s) {
    return switch (s) {
        case Circle c   -> Math.PI * c.r() * c.r();
        case Square sq  -> sq.a() * sq.a();
        case Triangle t -> 0.5 * t.base() * t.height();
        // default 不要 (Java が網羅性を保証)
    };
}

メソッドの細部

要素説明
戻り値の型void なら値を返さない
メソッド名lowerCamelCase 動詞で始める (calculateTotal)
引数0 個以上。final 可、varargs 可
throws 句検査例外を呼び出し側に通知
本体波括弧 + 文の並び
戻り値return 文 (void 以外は必須)
public int calculateTotal(int price, int quantity, double discount) throws IllegalArgumentException {
    if (quantity < 0) throw new IllegalArgumentException("quantity must be >= 0");
    double total = price * quantity * (1 - discount);
    return (int) total;
}

FAQ

Q: 1 つの .java ファイルに複数クラスを書ける?
A: 書けるが、public クラスは 1 つだけ でファイル名と一致が必須。残りは package-private。

Q: getter/setter は必須?
A: 慣習的に必須だが、record や DTO では不要 (自動生成 or public final で十分)。

Q: classinterface どちらを使う?
A: 「実装の共有」=>abstract class、「契約の定義」=>interface。Java 8+ では interface も default 実装を持てるので、迷ったら interface 優先。

編集
Post Share
子ページ
  1. クラスの定義
  2. initメソッド
  3. 関数の定義
  4. クラス変数とインスタンス変数
同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

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