チュートリアル

Java基礎:クラス

Java入門クラスオブジェクト指向
広告エリア

クラスの定義

public class Person {
    // フィールド(属性)
    private String name;
    private int age;

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

    // メソッド
    public void greet() {
        System.out.println("こんにちは、" + name + "です");
    }

    // ゲッター
    public String getName() {
        return name;
    }

    // セッター
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 0) {
            this.age = age;
        }
    }
}

// 使用
Person person = new Person("太郎", 25);
person.greet();
System.out.println(person.getName());

コンストラクタ

複数のコンストラクタ(オーバーロード)

public class Book {
    private String title;
    private String author;
    private int price;

    // 引数なしコンストラクタ
    public Book() {
        this.title = "無題";
        this.author = "不明";
        this.price = 0;
    }

    // 引数ありコンストラクタ
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
        this.price = 0;
    }

    // すべての引数ありコンストラクタ
    public Book(String title, String author, int price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }
}

Book book1 = new Book();
Book book2 = new Book("Java入門", "山田太郎");
Book book3 = new Book("Java入門", "山田太郎", 2800);

this()でコンストラクタ呼び出し

public class User {
    private String name;
    private String email;
    private boolean active;

    public User(String name) {
        this(name, null, true);  // 他のコンストラクタを呼び出し
    }

    public User(String name, String email) {
        this(name, email, true);
    }

    public User(String name, String email, boolean active) {
        this.name = name;
        this.email = email;
        this.active = active;
    }
}

アクセス修飾子

修飾子クラス内パッケージ内サブクラスすべて
private×××
(なし)××
protected×
public
public class Example {
    private int privateField;      // このクラス内のみ
    int packageField;              // 同じパッケージ内
    protected int protectedField;  // サブクラスからも
    public int publicField;        // どこからでも

    private void privateMethod() {}
    void packageMethod() {}
    protected void protectedMethod() {}
    public void publicMethod() {}
}

static メンバー

静的フィールド

public class Counter {
    private static int count = 0;  // クラス変数
    private int id;                // インスタンス変数

    public Counter() {
        count++;
        this.id = count;
    }

    public static int getCount() {
        return count;
    }

    public int getId() {
        return id;
    }
}

Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();

System.out.println(Counter.getCount());  // 3
System.out.println(c1.getId());          // 1
System.out.println(c3.getId());          // 3

静的メソッド

public class MathUtils {
    public static final double PI = 3.14159;

    public static int add(int a, int b) {
        return a + b;
    }

    public static int max(int a, int b) {
        return (a > b) ? a : b;
    }
}

// クラス名で呼び出し
int sum = MathUtils.add(3, 5);
double pi = MathUtils.PI;

静的初期化ブロック

public class Config {
    private static Map<String, String> settings;

    static {
        // クラスロード時に1回だけ実行
        settings = new HashMap<>();
        settings.put("debug", "true");
        settings.put("maxSize", "100");
    }

    public static String get(String key) {
        return settings.get(key);
    }
}

final キーワード

public class Constants {
    // 定数
    public static final int MAX_SIZE = 100;
    public static final String APP_NAME = "MyApp";
}

public class ImmutablePerson {
    // finalフィールドは変更不可
    private final String name;
    private final int birthYear;

    public ImmutablePerson(String name, int birthYear) {
        this.name = name;
        this.birthYear = birthYear;
    }

    public String getName() {
        return name;
    }

    public int getBirthYear() {
        return birthYear;
    }
}

内部クラス

インナークラス

public class Outer {
    private int value = 10;

    public class Inner {
        public void show() {
            // 外部クラスのフィールドにアクセス可能
            System.out.println("Value: " + value);
        }
    }
}

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

静的内部クラス

public class Container {
    private static int count = 0;

    public static class Helper {
        public void help() {
            // 静的フィールドのみアクセス可能
            System.out.println("Count: " + count);
        }
    }
}

Container.Helper helper = new Container.Helper();
helper.help();

匿名クラス

interface Greeting {
    void greet();
}

public class Main {
    public static void main(String[] args) {
        // 匿名クラス
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("こんにちは!");
            }
        };

        greeting.greet();
    }
}

record(Java 16以降)

不変データクラスを簡潔に定義します。

// recordの定義
public record Point(int x, int y) {}

// 使用
Point p = new Point(10, 20);
System.out.println(p.x());  // 10
System.out.println(p.y());  // 20
System.out.println(p);      // Point[x=10, y=20]

// メソッドを追加可能
public record Rectangle(int width, int height) {
    public int area() {
        return width * height;
    }
}

実践例:銀行口座

public class BankAccount {
    private static int nextAccountNumber = 1000;

    private final int accountNumber;
    private String ownerName;
    private double balance;

    public BankAccount(String ownerName) {
        this(ownerName, 0);
    }

    public BankAccount(String ownerName, double initialBalance) {
        this.accountNumber = nextAccountNumber++;
        this.ownerName = ownerName;
        this.balance = initialBalance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println(amount + "円を入金しました。残高: " + balance + "円");
        }
    }

    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println(amount + "円を出金しました。残高: " + balance + "円");
            return true;
        }
        System.out.println("出金できませんでした。");
        return false;
    }

    // ゲッター
    public int getAccountNumber() { return accountNumber; }
    public String getOwnerName() { return ownerName; }
    public double getBalance() { return balance; }

    @Override
    public String toString() {
        return String.format("口座番号: %d, 名義: %s, 残高: %.0f円",
            accountNumber, ownerName, balance);
    }
}

まとめ

  • クラスはフィールド、コンストラクタ、メソッドで構成
  • privateでカプセル化、ゲッター/セッターで公開
  • コンストラクタのオーバーロードで柔軟な初期化
  • staticでクラスレベルのメンバー
  • finalで変更不可のフィールドや定数
  • recordで不変データクラスを簡潔に定義

次回は継承とインターフェースについて学びます。

広告エリア