Javaのメソッドとクラス基礎

2025-08-01

はじめに

Javaプログラミングにおいて、メソッドとクラスの理解はオブジェクト指向プログラミング(OOP)への重要な第一歩です。この記事では、すでにJavaの基本文法を理解している方を対象に、メソッドの定義・利用方法、そしてクラスの作成とその中でのメソッド活用について詳しく解説します。

メソッドとクラスを学ぶことで得られるメリット:

  • コードの再利用性が向上する
  • プログラムの構造が整理され、保守性が高まる
  • 複雑な問題を小さな単位に分割して解決できる
  • オブジェクト指向プログラミングの基礎が身につく

メソッドの基本

メソッドとは?

メソッドは、特定のタスクを実行するためのコードのブロックです。複数の操作を1つにまとめ、名前を付けて繰り返し利用できるようにします。

メソッドの定義構文

[アクセス修飾子] [static] 戻り値の型 メソッド名(パラメータリスト) {
    // メソッドの処理
    return 戻り値; // voidの場合は不要
}

具体例:簡単な加算メソッド

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

メソッドの呼び出し

定義したメソッドは、次のように呼び出せます。

int result = add(5, 3);  // resultには8が代入される
System.out.println("5 + 3 = " + result);

様々なメソッドの例

戻り値なし(void)のメソッド

public static void greet(String name) {
    System.out.println("こんにちは、" + name + "さん!");
}

複数のパラメータを持つメソッド

public static double calculateBMI(double weight, double height) {
    return weight / (height * height);
}

条件分岐を含むメソッド

public static String judgeGrade(int score) {
    if (score >= 90) return "A";
    else if (score >= 80) return "B";
    else if (score >= 70) return "C";
    else if (score >= 60) return "D";
    else return "F";
}

メソッドの活用テクニック

オーバーロード(多重定義)

同じ名前で異なるパラメータリストを持つメソッドを複数定義できます。

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

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

public static int max(int a, int b, int c) {
    return max(max(a, b), c);
}

再帰メソッド

メソッドが自分自身を呼び出すことも可能です。

public static int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

可変長引数

引数の数を変えられるメソッドを作成できます。

public static double average(int... numbers) {
    int sum = 0;
    for (int num : numbers) {
        sum += num;
    }
    return (double)sum / numbers.length;
}

// 使用例
double avg1 = average(1, 2, 3);       // 2.0
double avg2 = average(5, 10, 15, 20); // 12.5

クラスの基礎

クラスとは?

クラスは、オブジェクトの設計図のようなものです。関連するデータ(フィールド)と操作(メソッド)を1つにまとめます。

クラスの定義構文

[アクセス修飾子] class クラス名 {
    // フィールド(メンバ変数)
    // コンストラクタ
    // メソッド
}

簡単なクラスの例

BankAccountクラス

public class BankAccount {
    // フィールド
    private String owner;
    private double balance;

    // コンストラクタ
    public BankAccount(String owner, double initialBalance) {
        this.owner = owner;
        this.balance = initialBalance;
    }

    // メソッド
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println(amount + "円預けました。残高: " + balance);
        }
    }

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

    public void displayBalance() {
        System.out.println(owner + "さんの残高: " + balance + "円");
    }
}

クラスの使用例

public class Main {
    public static void main(String[] args) {
        // BankAccountオブジェクトの作成
        BankAccount account = new BankAccount("山田太郎", 10000);

        // メソッドの呼び出し
        account.displayBalance();  // 山田太郎さんの残高: 10000.0円
        account.deposit(5000);    // 5000.0円預けました。残高: 15000.0
        account.withdraw(3000);   // 3000.0円引き出しました。残高: 12000.0
        account.withdraw(15000);   // 引き出しできません。
    }
}

クラス内のメソッド詳細

インスタンスメソッド vs スタティックメソッド

特徴インスタンスメソッドスタティックメソッド
呼び出し方法オブジェクトを通して呼び出すクラス名で直接呼び出す
thisの有無あり(現在のオブジェクトを参照)なし
フィールドアクセスインスタンスフィールドにアクセス可能staticフィールドのみアクセス可能
使用例オブジェクトの状態を操作・取得するユーティリティ関数など

スタティックメソッドの例

public class MathUtils {
    public static int square(int num) {
        return num * num;
    }
}

// 呼び出し例
int result = MathUtils.square(5);  // 25

ゲッターとセッター

フィールドを安全に操作するためのメソッドです。

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

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

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

    public int getAge() {
        return age;
    }

    // セッター
    public void setName(String name) {
        if (name != null && !name.isEmpty()) {
            this.name = name;
        }
    }

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

メソッドチェーン

メソッドがthisを返すことで、呼び出しを連鎖させられます。

public class StringBuilderExample {
    private StringBuilder builder = new StringBuilder();

    public StringBuilderExample append(String str) {
        builder.append(str);
        return this;
    }

    public String toString() {
        return builder.toString();
    }
}

// 使用例
String result = new StringBuilderExample()
    .append("Hello")
    .append(" ")
    .append("World!")
    .toString();  // "Hello World!"

実践的なクラス設計例

図形クラスの例

public class Rectangle {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getArea() {
        return width * height;
    }

    public double getPerimeter() {
        return 2 * (width + height);
    }

    public boolean isSquare() {
        return width == height;
    }

    public void scale(double factor) {
        width *= factor;
        height *= factor;
    }

    // ゲッターとセッター
    public double getWidth() { return width; }
    public double getHeight() { return height; }
    public void setWidth(double width) { this.width = width; }
    public void setHeight(double height) { this.height = height; }
}

学生成績管理システム

import java.util.ArrayList;
import java.util.List;

public class Student {
    private String name;
    private List grades = new ArrayList<>();

    public Student(String name) {
        this.name = name;
    }

    public void addGrade(int grade) {
        if (grade >= 0 && grade <= 100) {
            grades.add(grade);
        }
    }

    public double getAverage() {
        if (grades.isEmpty()) return 0;

        int sum = 0;
        for (int grade : grades) {
            sum += grade;
        }
        return (double)sum / grades.size();
    }

    public String getGradeReport() {
        double avg = getAverage();
        if (avg >= 90) return "A";
        else if (avg >= 80) return "B";
        else if (avg >= 70) return "C";
        else if (avg >= 60) return "D";
        else return "F";
    }

    // ゲッター
    public String getName() { return name; }
    public List getGrades() { return new ArrayList<>(grades); }
}

よくある間違いとベストプラクティス

よくある間違い

  1. メソッドの戻り値の型を忘れる
   public add(int a, int b) {  // 戻り値の型がない
       return a + b;
   }
  1. staticとインスタンスの混同
   public class Example {
       private int value;

       public static void printValue() {
           System.out.println(value);  // エラー: staticメソッドからインスタンス変数にアクセスできない
       }
   }
  1. 不適切なスコープのメソッド
   private void criticalOperation() {  // privateなのに外部から呼び出そうとする
       // 重要な処理
   }

ベストプラクティス

  1. 単一責任の原則: 1つのメソッドは1つのことだけを行う
  2. 説明的な名前: メソッド名から機能がわかるようにする
  3. 適切な長さ: メソッドは1画面に収まる程度(約20~30行以内)に
  4. 副作用の最小化: メソッドが予期せぬ状態変更を起こさないように
  5. ドキュメンテーションコメント: メソッドの目的、パラメータ、戻り値を説明する
/**
 * 与えられた年がうるう年かどうかを判定します。
 * 
 * @param year 判定する年(西暦)
 * @return うるう年の場合はtrue、そうでない場合はfalse
 */
public static boolean isLeapYear(int year) {
    if (year % 4 != 0) return false;
    if (year % 100 != 0) return true;
    return year % 400 == 0;
}

練習問題

理解を深めるための練習問題を用意しました。実際にコードを書いて試してみましょう。

問題1: 計算機クラス

以下の機能を持つCalculatorクラスを作成してください。

  • add(int a, int b): 加算
  • subtract(int a, int b): 減算
  • multiply(int a, int b): 乗算
  • divide(int a, int b): 除算(0除算に注意)
  • すべてのメソッドは計算結果を返す

問題2: 本クラス

Bookクラスを作成し、以下の要件を満たしてください。

  • フィールド: タイトル、著者、価格、在庫数
  • メソッド:
  • 在庫を増減させるメソッド
  • 本の情報を表示するメソッド
  • 割引を適用するメソッド

問題3: パスワード検証

次の条件をすべて満たすパスワードかどうかを検証するメソッドを作成してください。

  • 8文字以上
  • 大文字と小文字のアルファベットを含む
  • 少なくとも1つの数字を含む
  • 特殊文字(!@#$%^&*)のいずれかを含む

問題4: 銀行システム拡張

BankAccountクラスを拡張し、以下の機能を追加してください。

  • 口座番号(自動生成)
  • 取引履歴の記録
  • 利息の計算と追加
  • 他の口座への送金

次のステップ

メソッドとクラスの基礎を理解したら、以下のトピックに進みましょう:

  1. カプセル化とアクセス制御 - private/publicの適切な使い分け
  2. 継承 - 既存クラスを拡張する
  3. ポリモーフィズム - 同じインターフェースで異なる動作
  4. インターフェースと抽象クラス - より柔軟な設計
  5. 例外処理 - エラーへの対処方法

さらに学ぶためのリソース:

まとめ

この記事では、Javaのメソッドとクラスの基礎について詳しく解説しました。重要なポイントをまとめます:

  1. メソッドは特定のタスクを実行するコードブロックで、再利用性を高める
  2. クラスはオブジェクトの設計図で、データと操作をカプセル化する
  3. インスタンスメソッドはオブジェクトの状態を操作し、スタティックメソッドはクラスレベルで機能する
  4. ゲッターとセッターを使用してフィールドへの安全なアクセスを提供する
  5. 適切なクラス設計がコードの保守性と拡張性を決定する

メソッドとクラスはJavaプログラミングの核心です。実際にコードを書きながら、これらの概念をしっかりと身につけていきましょう。最初はシンプルなクラスから始め、徐々に複雑なシステムを設計できるようになっていきます。Happy coding!