やさしいJavaの学習後にやってみる実践ハンズオン！

# やさしいJava 実践ハンズオン

## 目次
1. [概要](#概要)
2. [前提条件](#前提条件)
3. [基本文法の確認演習](#基本文法の確認演習)
4. [オブジェクト指向プログラミング演習](#オブジェクト指向プログラミング演習)
5. [実践的なアプリケーション開発](#実践的なアプリケーション開発)
6. [発展課題](#発展課題)

## 概要
このハンズオンは「やさしいJava」の学習内容を実践的に定着させるための演習プログラムです。基本概念の理解から実践的なアプリケーション開発まで、段階的に学習を進めることができます。

## 前提条件
* 「やさしいJava」の基本概念を学習していること
* Eclipse/IntelliJなどの開発環境が準備されていること
* JDK 11以上がインストールされていること

## 基本文法の確認演習

### 演習1-1: 変数と演算子
基本的な計算処理を実装します。

```java
public static void exercise1_1() {
    // 課題: 以下の計算結果を求めてください
    int a = 10;
    int b = 3;
    
    // TODO: 
    // 1. a と b の加算
    // 2. a と b の減算
    // 3. a と b の乗算
    // 4. a と b の除算（小数点以下も表示）
    // 5. a と b の余り
}
```

**解答例**:
```java
public static void exercise1_1() {
    int a = 10;
    int b = 3;
    
    System.out.println("加算: " + (a + b));      // 13
    System.out.println("減算: " + (a - b));      // 7
    System.out.println("乗算: " + (a * b));      // 30
    System.out.println("除算: " + (float)a / b); // 3.3333...
    System.out.println("余り: " + (a % b));      // 1
}
```

### 演習1-2: 条件分岐
点数から成績を判定するプログラムを作成します。

```java
public static void exercise1_2(int score) {
    // 課題: 点数から成績を判定するプログラムを作成してください
    // 90点以上: "優"
    // 80点以上: "良"
    // 70点以上: "可"
    // 70点未満: "不可"
    
    // TODO: 条件分岐を実装
}
```

**解答例**:
```java
public static void exercise1_2(int score) {
    String grade;
    if (score >= 90) {
        grade = "優";
    } else if (score >= 80) {
        grade = "良";
    } else if (score >= 70) {
        grade = "可";
    } else {
        grade = "不可";
    }
    System.out.println("成績: " + grade);
}
```

### 演習1-3: 繰り返し処理
1から100までの偶数の和を求めます。

```java
public static void exercise1_3() {
    // 課題: 1から100までの偶数の和を求めてください
    // TODO: for文を使用して計算
}
```

**解答例**:
```java
public static void exercise1_3() {
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        if (i % 2 == 0) {
            sum += i;
        }
    }
    System.out.println("1から100までの偶数の和: " + sum);
}
```

## オブジェクト指向プログラミング演習

### 演習2-1: クラスとオブジェクト
書籍を表すクラスを実装します。

```java
class Book {
    // TODO: 
    // 1. 書籍を表すフィールドを定義（タイトル、著者、価格）
    // 2. コンストラクタの実装
    // 3. getterとsetterの実装
    // 4. 書籍情報を表示するメソッドの実装
}
```

**解答例**:
```java
class Book {
    private String title;
    private String author;
    private int price;
    
    public Book(String title, String author, int price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }
    
    // getterとsetter
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
    public int getPrice() { return price; }
    public void setPrice(int price) { this.price = price; }
    
    public void displayInfo() {
        System.out.println("書籍情報:");
        System.out.println("タイトル: " + title);
        System.out.println("著者: " + author);
        System.out.println("価格: " + price + "円");
    }
}
```

### 演習2-2: 継承と多態性
商品クラスと割引商品クラスを実装します。

```java
class Product {
    protected String name;
    protected int price;
    
    // TODO:
    // 1. コンストラクタの実装
    // 2. 税込価格を計算するメソッドの実装（税率10%）
}

class DiscountProduct extends Product {
    private int discountRate;
    
    // TODO:
    // 1. コンストラクタの実装
    // 2. 割引後の税込価格を計算するメソッドの実装
}
```

**解答例**:
```java
class Product {
    protected String name;
    protected int price;
    
    public Product(String name, int price) {
        this.name = name;
        this.price = price;
    }
    
    public int calculatePrice() {
        return (int)(price * 1.10); // 税率10%
    }
}

class DiscountProduct extends Product {
    private int discountRate;
    
    public DiscountProduct(String name, int price, int discountRate) {
        super(name, price);
        this.discountRate = discountRate;
    }
    
    @Override
    public int calculatePrice() {
        int priceBeforeTax = price * (100 - discountRate) / 100;
        return (int)(priceBeforeTax * 1.10);
    }
}
```

## 実践的なアプリケーション開発

### 演習3-1: 簡易家計簿アプリケーション
取引を記録し、集計するアプリケーションを作成します。

```java
class Transaction {
    // TODO:
    // 1. 取引日、カテゴリ、金額のフィールドを定義
    // 2. コンストラクタの実装
    // 3. getterの実装
}

class HouseholdAccount {
    private ArrayList<Transaction> transactions;
    
    // TODO:
    // 1. 取引を追加するメソッド
    // 2. カテゴリ別の集計を行うメソッド
    // 3. 月次レポートを生成するメソッド
}
```

**解答例**:
```java
class Transaction {
    private String date;
    private String category;
    private int amount;
    
    public Transaction(String date, String category, int amount) {
        this.date = date;
        this.category = category;
        this.amount = amount;
    }
    
    public String getDate() { return date; }
    public String getCategory() { return category; }
    public int getAmount() { return amount; }
}

class HouseholdAccount {
    private ArrayList<Transaction> transactions;
    
    public HouseholdAccount() {
        transactions = new ArrayList<>();
    }
    
    public void addTransaction(Transaction transaction) {
        transactions.add(transaction);
    }
    
    public int getCategoryTotal(String category) {
        int total = 0;
        for (Transaction t : transactions) {
            if (t.getCategory().equals(category)) {
                total += t.getAmount();
            }
        }
        return total;
    }
    
    public void generateMonthlyReport(String month) {
        System.out.println(month + "の月次レポート");
        Map<String, Integer> categoryTotals = new HashMap<>();
        
        // カテゴリ別に集計
        for (Transaction t : transactions) {
            if (t.getDate().startsWith(month)) {
                String category = t.getCategory();
                categoryTotals.put(category, 
                    categoryTotals.getOrDefault(category, 0) + t.getAmount());
            }
        }
        
        // レポート出力
        for (Map.Entry<String, Integer> entry : categoryTotals.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue() + "円");
        }
    }
}
```

使用例:
```java
public class MainExample {
    public static void main(String[] args) {
        HouseholdAccount account = new HouseholdAccount();
        
        // 取引を追加
        account.addTransaction(
            new Transaction("2025-01-01", "食費", 3000));
        account.addTransaction(
            new Transaction("2025-01-02", "交通費", 500));
        account.addTransaction(
            new Transaction("2025-01-03", "食費", 2500));
        
        // 月次レポートを生成
        account.generateMonthlyReport("2025-01");
        
        // カテゴリ別集計を表示
        System.out.println("食費合計: " + account.getCategoryTotal("食費") + "円");
    }
}
```

## 発展課題

さらなる理解を深めるため、以下の課題に挑戦してください：

### 1. 図書館管理システム
* 本の貸し出し/返却機能
* 会員管理機能
* 蔵書検索機能

https://qiita.com/Hemmy7/items/ede6f6303dbb732ce26d

### 2. 銀行口座管理システム
* 入出金機能
* 残高照会機能
* 取引履歴管理

### 3. タスク管理アプリケーション
* タスクの追加/編集/削除
* 優先度設定
* 期限管理

## 学習のポイント

1. **基本文法の確実な理解**
   * 変数と演算子の適切な使用
   * 制御構造の使い分け
   * 型変換の理解

2. **オブジェクト指向の原則**
   * カプセル化の実践
   * 継承の適切な使用
   * ポリモーフィズムの活用

3. **実践的な実装スキル**
   * エラー処理の考慮
   * コードの再利用性
   * 保守性の高いコード設計

4. **コーディング規約**
   * 命名規則の遵守
   * 適切なコメント記述
   * インデントの統一