クラスを定義する
このレッスンで分かること
- クラスはオブジェクトの設計図、インスタンスは設計図から作る実体
public class クラス名 { ... }の形で定義、ファイル名と一致させます- 最小例は
static class Book {} ... Book b = new Book();
クラスを定義する とは
Java の世界の基本単位、クラスを定義する意味と書き方を学ぼう。本レッスンでは、クラスを定義する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
クラスを定義する
ここまでで変数、計算、条件分岐、繰り返し、メソッドと、Java プログラムを動かす基本道具が一通り揃いました。実は、これまでずっと当たり前のように書いてきた public class Solution { ... } という外側の枠こそが、Java の世界でいちばん大切な部品、クラス (class) です。今回はこのクラスを定義することの意味そのものに向き合っていきます。
Javaは徹底したオブジェクト指向言語で、すべてのコードがクラスの中に入ります。PythonやJavaScriptのようにファイルの先頭からいきなり処理を書くことはできず、必ずclassという箱を作って、その中にメソッドや変数を置く、というのが Java の流儀です。
クラスとは何か
クラスを一言で言うと、オブジェクトの設計図 です。たとえば「本」というモノを Java の世界で扱いたいとき、まず「本にはタイトルがあって、著者がいて、ページ数がある」という設計図を 1 枚書きます。これがクラスです。その設計図をもとに「ハリー・ポッター」や「吾輩は猫である」のような具体的な 1 冊 1 冊を生み出す、これが インスタンス (instance) や オブジェクト (object) と呼ばれるものです。
クラスを定義することのメリットは、次のとおりです。
- 関連するデータと処理をひとまとめにできる — タイトル、著者、ページ数といったデータと、「目次を表示する」「ページを進める」といった処理を 1 つの箱にまとめられる
- 同じ設計図から何個でもインスタンスを作れる —
Bookクラスを 1 つ書けば、本のオブジェクトを100個でも1000個でも生み出せる - 現実世界の概念を素直にコードに写せる — 「ユーザー」「商品」「注文」のような言葉をそのままクラス名にすれば、コードを読んだ人がイメージしやすい
- 再利用と拡張がしやすい — 後で
継承(extends) やインターフェイス(interface) を使って、設計図同士を組み合わせられるようになる
クラスとインスタンスの関係は、たい焼きの型と、その型から焼かれる 1 個 1 個のたい焼きにたとえられます。型 = クラス、たい焼き = インスタンス、と覚えておくとイメージがブレません。
クラスとインスタンスの関係を図にすると、次のような形になります。同じ Book という設計図から、複数の本オブジェクトが生み出される様子を頭の中に描いてみてください。
図の関係を箇条書きで整理すると、次の通りです。
Bookクラスは 1 つの設計図new Book()のたびに新しいインスタンスが生まれる- インスタンス 1 は「ハリー・ポッター」、インスタンス 2 は「吾輩は猫である」のように独立した値を持てる
- クラスは型、インスタンスは値、と区別する
設計図 (クラス) はあくまで 1 枚で、そこから何冊でも具体的な本 (インスタンス) を生み出せる、という関係をしっかりつかんでください。
クラス定義の構文
Java でいちばんシンプルなクラスは、次のような形になります。
Java
public class Book {
}たった 2 行ですが、これでも立派なクラスの定義です。左から順に分解しましょう。
public— どこからでも使ってよいというアクセス修飾子class— これがクラス定義であることを示すキーワードBook— クラスの名前。慣習としてPascalCase(先頭大文字 + 単語の区切りも大文字) で書く{ ... }— このクラスの中身が入る本体
クラスの本体には、後のレッスンで詳しく扱う フィールド (クラスが持つデータ) と メソッド (クラスが行う処理) を書き並べていきます。たとえば Book クラスにタイトルとページ数を持たせて、目次を表示するメソッドを書くと、次のような形になります。
Java
public class Book {
String title;
int pages;
public String describe() {
return title + " (" + pages + "ページ)";
}
}title と pages が フィールド、describe() が メソッド です。今回のレッスンではフィールドとメソッドの詳しい書き方には踏み込みませんが、「クラスの中にはこの 2 種類のものが並ぶ」というイメージだけ持っておきましょう。
フィールドとメソッドを 1 つの箱にまとめて、外からはその箱を 1 つの単位として扱う、これを
カプセル化(encapsulation) と呼びます。オブジェクト指向の 3 大原則のうちの 1 つで、これから何度も登場する考え方です。
クラス名の慣習とファイル名のルール
Java のクラスには、見た目を整えるための強い慣習と、コンパイラがチェックする厳密なルールの両方があります。
- クラス名は
PascalCase—BookUserProfileShoppingCartのように、先頭も単語の区切りも大文字で書く - 動詞より名詞 — クラスは「モノ」を表すので、
PrintBookではなくBook、SaveUserではなくUserのように名詞で命名する public classのときはファイル名と完全一致 —public class Bookを書いたら、ファイル名は必ずBook.javaにする- 1 つの
.javaファイルにpublic classは 1 つだけ —publicのクラスを 2 つ書こうとするとコンパイルエラー
ファイル名とクラス名を一致させるルールは、最初は面倒に感じますが、後でクラスが何百個に増えたときに「このクラスはどのファイル?」と迷わずに済む大きなメリットになります。
変数名やメソッド名 (camelCase) と、クラス名 (PascalCase) で大文字小文字の使い方が違う点に注意してください。book という変数と Book というクラスは、Java の世界では別物として扱われます。
よくある間違い
クラスを書き始めたばかりの頃に、誰もがよくつまずく落とし穴を 3 つ紹介します。
- クラス名を小文字で始める —
public class book { ... }のように小文字で書くとコンパイル自体は通ってしまうことがあるものの、Javaの世界ではクラス名を小文字で始めるのは強いアンチパターンです。チームのコードレビューでも一発で指摘されます。必ずBookのように大文字始まりで書きましょう - ファイル名とクラス名が食い違う —
Book.javaの中にpublic class Library { ... }と書くと、class Library is public, should be declared in a file named Library.javaというエラーで止まります - 1 つのファイルに
public classを複数書く —BookとLibraryの両方をpublic classで書こうとすると同じくコンパイルエラーになります
もうひとつ地味に多いのが、class キーワードの書き忘れです。public Book { ... } のように class を省略すると「class interface or enum expected」というエラーが出ます。
エラーメッセージは敵ではなく味方です。
should be declared in a file named ...と出たらファイル名とクラス名の不一致、class ... is public, should be declared ...と出たらpublic classのルール違反、と原因を予想できるようになると、修正のスピードが一気に上がります。
ここまでの要点
クラスは設計図、new でインスタンス化。クラス名は PascalCase、ファイル名と一致、1 ファイル 1 public class。class キーワードを忘れない。
やってみよう
それでは課題に挑戦しましょう。今回は本文どおりに Book クラスを実際に定義して、そのインスタンスを new で作る ところまで自分の手で書きます。
- 右側のエディタを開く
Solutionクラスの中にstatic class Book { }を書く (本体は空でかまいません)createBook()の中でBook b = new Book();を書き、b.getClass().getSimpleName()をreturnする- 「実行」ボタンを押して、テストが緑になることを確認する
テストは戻り値が "Book" という文字列であることをチェックします。これは「Book という名前のクラスを定義した」「そのクラスから 1 つインスタンスを取り出せた」という 2 点を、戻り値の文字列で確かめる作りです。固定で return "Book"; と書くと一見テストは通りますが、本レッスンの目的は クラス定義そのものを書くこと です。必ず static class Book を自分で書いて、new Book() を経由するようにしてください。
慣れてきたら、Book クラスの中に String title; のようなフィールドを 1 つ足してみると、次のレッスン (フィールドを持たせる) の予習になります。
クラスは Java プログラムを 組み立てる ためのいちばん大きな部品です。ここから先のレッスンで、フィールド、コンストラクタ、new でインスタンスを生み出す、メソッドからフィールドを操作する、と少しずつ世界が広がっていきます。
よくある質問
Q. クラスと関数はどう使い分けますか?
A. 状態(フィールド)を持たせて関連する処理をまとめたいときはクラス、純粋な計算だけなら関数で十分です。Java のように関数を単独で持てない言語ではクラス必須ですが、JS/Python はモジュール関数だけでも十分です。OOP の継承を活かすかどうかで判断しましょう。
Q. private と public の使い分けは?
A. フィールドは原則 private にして外から触らせず、getter / setter 経由でアクセスさせるのがカプセル化の基本です。public は呼び出し元に公開する API、private は内部実装の隠蔽。後から内部を変えても利用側が壊れないメリットがあります。
Q. 1 ファイルに複数クラスを書けますか?
A. Java は 1 つの public クラスにつき同じファイル名が必要です。public でない補助クラスは同じファイルに置けます。JavaScript/Python は何個でも置けますが、再利用性のために 1 ファイル 1 クラスを基本にした方が読み手に優しいです。
次のレッスン
次は クラスにフィールドを持たせる で、Java の世界の基本単位、クラスを定義する意味と書き方を学ぼう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- クラス定義 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. クラス定義 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
Solutionの中にBookクラスを定義すること (本文のstatic class Book { }で十分)createBook()の中でnew Book()を使ってインスタンスを作ること- 戻り値はそのインスタンスのクラス名
"Book"という文字列にすること
入出力例
test-cases.txt
createBook() → "Book"
createBook() → "Book"