007-001-002

クラスの作成:書籍情報マネージャー

中級

問題説明

【解説】

🎯 問題の概要

この問題では、書籍の情報を管理するBookクラスを作成します。クラスの基本的な要素であるフィールド、コンストラクタメソッドの使い方を学び、データをカプセル化する方法を理解します。表形式で情報を表示することで、実行結果が視覚的に分かりやすくなり、クラスが実際にどのように動作するかを確認できます。

📚 前提知識の確認

この問題を解くために必要な基礎知識:

クラスとは

クラスは、オブジェクトの設計図です。建築でいえば「設計図」、料理でいえば「レシピ」のようなものです。クラスを定義することで、同じ構造を持つ複数のオブジェクトを作成できます。

フィールド(インスタンス変数)

フィールドは、クラスが保持するデータです。この問題では、title(タイトル)、author(著者)、price(価格)、pages(ページ数)という4つのフィールドを定義します。フィールドは通常privateで宣言し、クラスの外部から直接アクセスできないようにします。

コンストラクタ

コンストラクタは、クラスのインスタンスを作成する際に自動的に呼ばれる特殊なメソッドです。クラス名と同じ名前で、戻り値の型を書きません。コンストラクタの役割は、フィールドに初期値を設定することです。

メソッド

メソッドは、クラスが持つ動作(処理)を定義します。この問題では、getInfo()というメソッドで書籍情報を表形式で返します。メソッドはpublicで宣言し、クラスの外部から呼び出せるようにします。

💡 解法のポイント

1. フィールドの定義

書籍の情報を保持するために4つのフィールドを定義します。フィールドはprivateで宣言し、クラス内部でのみアクセスできるようにします。

private String title;   // タイトル
private String author;  // 著者
private int price;      // 価格
private int pages;      // ページ数
```java

### 2. コンストラクタでの初期化
コンストラクタは4つのパラメータを受け取り、それぞれのフィールドに値を代入します。thisキーワードを使うことで、パラメータとフィールドを区別します。

```java
public Book(String title, String author, int price, int pages) {
    this.title = title;   // this.titleはフィールド、titleはパラメータ
    this.author = author;
    this.price = price;
    this.pages = pages;
}
```java

### 3. getInfo()メソッドの実装
getInfo()メソッドは、フィールドに保存された値を使って表形式の文字列を作成し、返します。改行文字(\n)を使って複数行の文字列を作成します。

### 4. エラーハンドリング
価格やページ数が負の値の場合、エラーメッセージを返します。これにより、不正なデータに対して適切に対応できます。

## 📖 コード解説(ステップバイステップ)

### ステップ1: クラスとフィールドの定義
```java
public class Book {
    private String title;
    private String author;
    private int price;
    private int pages;
```java
Bookという名前のpublicクラスを定義します。4つのprivateフィールドを宣言し、書籍の情報を保持します。privateにすることで、クラスの外部から直接アクセスできなくなり、データの整合性を保つことができます。

### ステップ2: コンストラクタの実装
```java
public Book(String title, String author, int price, int pages) {
    this.title = title;
    this.author = author;
    this.price = price;
    this.pages = pages;
}
```java
コンストラクタは、クラス名と同じ「Book」という名前で定義します。4つのパラメータを受け取り、それぞれのフィールドに値を代入します。thisキーワードは「このオブジェクトの」という意味で、フィールドとパラメータを区別するために使います。

### ステップ3: 入力検証
```java
if (price < 0) {
    return "Error: Price must be positive";
}
if (pages < 0) {
    return "Error: Pages must be positive";
}
```java
getInfo()メソッドの最初で、価格とページ数が負の値でないかチェックします。負の値が見つかった場合、エラーメッセージを返して処理を終了します。これは「早期リターンパターン」と呼ばれる手法で、エラーケースを先に処理することでコードが読みやすくなります。

### ステップ4: 表形式の文字列作成
```java
return "====================\n" +
       "Book Information\n" +
       "====================\n" +
       "Title  : " + title + "\n" +
       "Author : " + author + "\n" +
       "Price  : " + price + "yen\n" +
       "Pages  : " + pages + "pages\n" +
       "====================";
```java
文字列の連結(+<a href="https://javadrill.tech/problems/003">演算子</a>)を使って、表形式の文字列を作成します。\nは改行文字で、実行結果が複数行になります。罫線(=)を使うことで、情報が見やすくなります。

## ⚠️ よくある間違い

### 1. コンストラクタで戻り値の型を書いてしまう
```java
// ❌ 間違い
public void Book(String title, String author, int price, int pages) {
    // ...
}

// ✅ 正しい
public Book(String title, String author, int price, int pages) {
    // ...
}
```java
**理由**: コンストラクタは戻り値の型を持ちません。voidやその他の型を書くと、コンストラクタではなく通常のメソッドになってしまいます。

### 2. thisキーワードを使わずにフィールドに代入
```java
// ❌ 間違い
public Book(String title, String author, int price, int pages) {
    title = title;  // パラメータに再代入しているだけ
    author = author;
}

// ✅ 正しい
public Book(String title, String author, int price, int pages) {
    this.title = title;  // フィールドに代入
    this.author = author;
}
```java
**理由**: thisを使わないと、パラメータ名とフィールド名が同じ場合、パラメータに再代入しているだけになり、フィールドに値が設定されません。

### 3. 改行文字を忘れる
```java
// ❌ 間違い(1行につながってしまう)
return "Book Information" + "Title: " + title + "Author: " + author;

// ✅ 正しい(改行が入って読みやすい)
return "Book Information\n" + "Title: " + title + "\n" + "Author: " + author;
```java
**理由**: 改行文字(\n)を入れないと、すべての情報が1行につながってしまい、読みづらくなります。

## 🚀 発展的な内容

さらに学習を深めるためのヒント:

### 1. アクセサメソッド(getter/setter)の追加
現在のコードでは、フィールドはprivateなので外部から直接アクセスできません。getTitle()setPrice()のようなメソッドを追加することで、フィールドの値を安全に取得・変更できます。

### 2. 複数のコンストラクタ(オーバーロード)
コンストラクタは複数定義できます。例えば、価格とページ数を指定しないコンストラクタを追加することで、より柔軟にインスタンスを作成できます。

### 3. toString()メソッドの<a href="https://javadrill.tech/problems/014/005">オーバーライド</a>
getInfo()の代わりにtoString()メソッドを<a href="https://javadrill.tech/problems/014/005">オーバーライド</a>することで、System.out.println(book)で直接情報を表示できるようになります。

### 4. より複雑なバリデーション
価格が負の値でないかだけでなく、タイトルが空文字列でないか、ページ数が妥当な範囲内かなど、より詳細な検証を追加できます。

## 🔗 関連する学習項目

次に学ぶべきトピックやこの問題と関連する概念:

- **アクセサメソッド(getter/setter)**(カテゴリ008-002- **メソッドのオーバーロード**(カテゴリ009- **<a href="https://javadrill.tech/problems/014">継承</a><a href="https://javadrill.tech/problems/015">ポリモーフィズム</a>**(カテゴリ010- **カプセル化とアクセス修飾子**(カテゴリ011- **クラス間の関係(委譲と集約)**(カテゴリ012

テストケース例

※ 出力例はプログラミングの国際標準に準拠し英語で表示しています

入力:
期待される出力:
====================
Book Information
====================
Title  : Java Intro
Author : Taro Tanaka
Price  : 2800yen
Pages  : 350pages
====================
入力:
期待される出力:
====================
Book Information
====================
Title  : Python Guide
Author : Hanako Yamada
Price  : 3500yen
Pages  : 280pages
====================
入力:
期待される出力:
====================
Book Information
====================
Title  : A
Author : B
Price  : 0yen
Pages  : 1pages
====================
入力:
期待される出力:
====================
Book Information
====================
Title  : Complete Programming Language Guide with Very Long Title
Author : Author With Long Name
Price  : 9999yen
Pages  : 999pages
====================
入力:
期待される出力:
Error: Price must be positive
入力:
期待される出力:
Error: Pages must be positive
❌ テストに失敗したケースがあります
❌ エラー発生

あなたの解答

現在のモード: 自分のコード
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// ここにコードを書いてください

sc.close();
}
}
0 B / 5 MB

残り 8 回実行可能