【本サイトではGoogleアドセンス、または、アフィリエイト広告を利用しています。】
オブジェクトとは?
クラスを理解する前に、まずオブジェクトとは何かを知っておく必要があります。
オブジェクトとは、物のことです。
と、これだけでは、ちょっと何言ってるかわからないですよね。
Javaに限らず、オブジェクト指向言語では、
世の中にある物すべてをオブジェクトという概念で扱います。
例えば、人や車、食べ物、パソコンもスマホもオブジェクトです。
もっと広く見ると、地球や宇宙もオブジェクトとして扱うことができます。
今あなたの目の前に見える物、すべてがオブジェクトです。
つまり、Javaの中では、すべてオブジェクトとして
プログラム化できるということです。
では目の前にある物をどうやってJavaでプログラム化するのか?
そこで登場するのが、クラスです。
オブジェクト指向については、以下で詳しく説明していますので
あわせて読んでいただくとより理解が深まると思います。
クラスとは?
Javaにおけるクラスとは、変数やメソッドなどを1つのグループにまとめたものです。
処理をジャンル分けしてまとめておく為の袋のようなイメージです。
Javaでは、その袋を中括弧「{}」のブロックで囲んで1つにまとめます。
どのようにジャンル分けするのかは、プログラマー次第なのですが、
基本的に、クラスはオブジェクト単位に分類して使います。
なぜなのか?
例えば、人のオブジェクトと、車のオブジェクトをそれぞれ作りたい時、
同じプログラムのブロック内に「食べる」といったメソッドや、
「ガソリン残量」のような変数が入り混じっているとどうでしょう?
こんな部屋みたいに、どこに何があるのかわからなくなってしまいます!
それに、人のオブジェクトが、ガソリン残量を持っていたり、
車のオブジェクトが何かを食べたりするのは、現実世界ではありえないです。
そういったことも踏まえて、Javaでは、
人や車といったオブジェクトをクラスという構造に整理して
動きを別々に扱えるように設計されています。
ということで、Javaでは、オブジェクトの実体(現実世界)にあわせて、
クラス単位でプログラムを書いていくのが基本となります。
クラスの概念については、以下で詳しく説明していますので
あわせて読んでいただくとより理解が深まると思います。
クラスの書き方
まずはクラスの書き方について説明します!
新しい用語が出てきますが後ほどサンプルコードを見ながら説明しますので、
まずはイメージだけ持っておいてください。
修飾子 class クラス名 { // フィールド 修飾子 型1 フィールド名1; 修飾子 型2 フィールド名2; … // コンストラクタ(省略可) 修飾子 クラス名(引数1, 引数2,…) { 初期化処理 } // メソッド 修飾子 戻り値の型 メソッド名(引数1, 引数2,…) { 処理 return 戻り値; } }
プログラムで例を書くと以下のような感じです。
エネルギー残量を持ったおはようロボ君をクラスにしてみました。
コンストラクタは省略しています。(後ほど使い方を説明します。)
class Robot {
// フィールド:エネルギー
int energy = 100;
// メソッド:あいさつ
public void goodMorning() {
System.out.println("おはようございまス!");
return;
}
}
このクラス単体では、単純に定義を行っただけの状態なので、
まだおはようロボ君は動きません。
変数やメソッドと同じく、どこかのプログラムから呼び出されて初めて動き出します。
今はまだ、おはようロボ君の設計図ができあがった状態ですね。
クラスの使い方(サンプルコード)
では、次に、クラスをどのように呼び出して、どのように扱うのか、
用語の説明とあわせてサンプルコードを見ていきましょう。
この例は、おはようロボ君のエネルギーがなくなるまで
繰り返しあいさつをするプログラムです。
package example;
// クラス:メイン処理実行用
public class Example {
// メイン処理
public static void main(String[] args) {
// おはようロボ作成
Robot robo = new Robot();
// エネルギーがなくなるまであいさつ
while (robo.goodMorning()) {
System.out.println("エネルギー残:" + robo.energy);
}
}
}
// クラス:おはようロボ
class Robot {
// フィールド:エネルギー
int energy = 100;
// メソッド:あいさつ
public boolean goodMorning() {
// あいさつするエネルギーが残っている場合
if (energy >= 15) {
System.out.println("おはようございまス!");
// あいさつしたらエネルギーを減らす
energy -= 15;
// あいさつ成功
return true;
}
// あいさつするエネルギーが残っていない場合
else {
System.out.println("エネルギーが足りませン。。");
// あいさつ失敗
return false;
}
}
}
実行結果は以下です!
おはようございまス!
エネルギー残:85
おはようございまス!
エネルギー残:70
おはようございまス!
エネルギー残:55
おはようございまス!
エネルギー残:40
おはようございまス!
エネルギー残:25
おはようございまス!
エネルギー残:10
エネルギーが足りませン。。
用語説明の前に、まずはサンプルコード全体の構成を見ていきましょう。
クラスとしては、mainメソッドを実行する為のExampleクラスと、
おはようロボ君を定義したRobotクラスの2つが登場します。
プログラムを実行した時の流れは以下のようになります。
① Exampleクラスのmainメソッドから処理開始。
② クラスRobotのインスタンスを作成。
③ エネルギーがなくなるまで、おはようロボ君があいさつを繰り返す。
補足として、③の動きは以下と同じ処理をしています。
難しければ読み替えてください。
// 判定結果
boolean result = true;
// エネルギーがなくなるまであいさつ
while (result) {
result = robo.goodMorning();
System.out.println("エネルギー残:" + robo.energy);
}
これらを踏まえて、今から用語の意味を1つ1つ説明していきます!
インスタンスとは?
サンプルコードの流れ②に登場してくる言葉です。
インスタンスとは、Javaで定義したクラスを実体化したものです。
あなたの目の前におはようロボ君が登場するのではなく、
Javaの世界の中で実体を持つということです。
つまり、言い換えると、クラスをインスタンスにすることで、
Javaの世界の中でオブジェクトを作成するということになります。
クラスとして定義した時点ではまだ設計図の段階です。
インスタンスにして初めて
Javaの世界のオブジェクトとして動き出すことができます。
また、クラスを実体化することを、インスタンス化するとも言います。
クラスをインスタンス化する方法は以下です。
クラス名 変数名 = new クラス名(引数1, 引数2, …);
Javaでは、new演算子を使うことで、
クラスをインスタンス化することができます。
引数は、コンストラクタを定義することで指定できるようになります。
定義しない場合は、引数なしの丸括弧「()」のみを書きます。
サンプルコード内でクラスをインスタンス化しているのはこの部分です。
Robot robo = new Robot();
これで、おはようロボ君のクラスRobotは、変数roboとしてインスタンス化します。
インスタンスとオブジェクトの違いは?
ここまでの説明で、理解したようでできていないことがあると思います。
インスタンスとオブジェクトと何が違うのでしょう?
それぞれ改めて説明すると、
インスタンスとは、Javaのクラスを実体化したものです。
オブジェクトとは、目の前にあるすべての物です。
ある視点から言えば同じですし、広く見れば違うということになります。
どういうことかというと、
オブジェクトとは、物と言うものを表現した概念です。
インスタンスは、Javaの世界におけるオブジェクトです。
つまり、インスタンスは、オブジェクトのうちの1つとも言えます。
言葉の定義の範囲が違うだけで、現実世界から見ると別物ですが、
Javaの世界から見ると、インスタンスとオブジェクトは同じです。
なので、Javaを扱うという部分だけで言えば、
インスタンス=オブジェクトとして理解して進めても良いですが、
広義的には違うということで覚えておいてください。
フィールドとは?
フィールドとは、クラスに紐づけて定義する変数のことです。
主に、クラスの性質や状態を管理する為に使います。
先ほどのサンプルコードの例で言うと、おはようロボ君のエネルギーです。
int energy = 100;
ゲームで言うと、勇者や魔王が持つステータスのようなものです。
オブジェクトそれぞれには、性質や状態があるので、
プログラムでそれらを表現する時に定義して使うことになります。
また、フィールドは、以下のように扱う人や文献によって
いろいろな呼び方をされますが、すべて同じものとして考えましょう。
フィールド変数 メンバ変数 インスタンス変数 プロパティ
や、ややこしい。。統一して欲しい。。
コンストラクタとは?
コンストラクタとは、クラスがインスタンス化される時に実行される処理のことです。
特に処理を行う必要がない時は、定義を省略することもできます。
主に、フィールドの値を初期化する時に使います。
おはようロボ君の例でコンストラクタを使うように少し書き換えてみます。
package example;
// クラス:メイン処理実行用
public class Example {
// メイン処理
public static void main(String[] args) {
// おはようロボ作成
Robot robo = new Robot(100);
// エネルギーがなくなるまであいさつ
while (robo.goodMorning()) {
System.out.println("エネルギー残:" + robo.energy);
}
}
}
// クラス:おはようロボ
class Robot {
// フィールド:エネルギー
int energy;
// コンストラクタ
public Robot(int energy) {
this.energy = energy;
}
// メソッド:あいさつ
public boolean goodMorning() {
// あいさつするエネルギーが残っている場合
if (energy >= 15) {
System.out.println("おはようございまス!");
// あいさつしたらエネルギーを減らす
energy -= 15;
// あいさつ成功
return true;
}
// あいさつするエネルギーが残っていない場合
else {
System.out.println("エネルギーが足りませン。。");
// あいさつ失敗
return false;
}
}
}
プログラムは変わりましたが、実行結果は先ほどの例と同じなので省略します。
サンプル中でコンストラクタを定義している部分は以下です。
名前はクラスと同じにする必要があります。
public Robot(int energy) {
this.energy = energy;
}
コンストラクタの中でフィールドenergyに値を入れて初期化するようにしたので、
フィールドenergyを定義している部分では値を代入しないようにしています。
(thisの使い方については後ほど説明します。)
int energy;
また、コンストラクタを定義したことで、インスタンス化する際に
エネルギーの量を自由に指定できるようになりました。
Robot robo = new Robot(100);
これを使えば、エネルギー量が10000になった、
真おはようロボ君を作ることだってできます。
このように、コンストラクタを定義することで、
値の初期化を行ったり、フィールドを動的に変えて、
様々なステータスを持ったインスタンスを作成することもできるようになります。
thisとは?使い方は?
コンストラクタ内に出てきた「this」についてお話します。
thisとは、クラス自身を表す時に使う変数です。
Javaであらかじめ用意された変数(予約語と呼びます。)なので
定義せずに使うことができます。
先ほどの例では、コンストラクタの引数に指定したenergyと、
クラスのフィールドenergyを同時に扱う必要がありました。
クラスをインスタンス化する時に「100」という値が引数として渡されるので、
それをフィールドに保存する為です。
しかし、プログラム内で以下のように書くとどうでしょう?
energy = energy;
Javaもプログラムを実行する時に、
あなたがどちらのenergyを指定しているのかまで判断できません。
また、プログラムを解釈する際には、スコープがより近いものが優先されるので、
どちらも引数energyとして扱われてしまいます。
プログラムの意図としては、
「フィールドenergyに、引数で指定されたenergyを代入する。」
ということなので、
フィールドと引数で同じ名前になった場合は、
値を区別する為に、フィールド側の変数にthisをつけて使います。
コンストラクタの中だけではなく、メソッド内の処理など、
クラス内の処理で同名の変数があり、フィールドを同時に扱う必要があれば、
同じように区別して使う必要があるので覚えておきましょう!
メソッドとは?
メソッドとは、一連の処理を1つにまとめたものですが、
クラスに紐づいて動作するメソッドは、
オブジェクトが持つ動作を表現する時などに使います。
人だと歩いたり、食べたり、息をすることもメソッドの1つです。
また、ごはんを食べる動作だけで言うと、口を開けたり、歯で噛んだり、
胃で消化するといった、自分で意識していない動きも1つの動作と言えます。
どの単位でメソッド化するのかルールは特にないので、
プログラムを組む人の感性で定義していくことになります。
このようなメソッドは、クラスを実体化したものに紐づくので、
インスタンスメソッドとも呼ばれます。
サンプルコードでは、おはようロボ君のあいさつの動きになります。
public boolean goodMorning() {
…
}
メソッドの詳細や定義方法については、以下で説明していますので、
あわせて読んでみてください。
メンバとは?
メンバとは、クラスを構成するフィールド、メソッドのことです。
サンプルコードで言うと、フィールドenergyはクラスRobotのメンバです。
同じく、メソッドgoodMorningはクラスRobotのメンバです。
呼び方はメンバーじゃなくて、メンバということですが、
クラスにいるメンバーと考えると覚えやすいのではないでしょうか。
メンバへのアクセス方法は?「.」(ドット)の使い方
クラスをインスタンス化した時に、そのインスタンスを動かしたり、
状態を見ることを、メンバにアクセスすると言います。
メンバにアクセスする方法は以下です。
インスタンス.フィールド インスタンス.メソッド
作成したインスタンスの後に、
「.」(ドット)をつけてフィールド名、またはメソッド名を書きます。
サンプルコードの例では、おはようロボ君を作成した後、
残りエネルギーを見たり、あいさつをしたりする時にメンバを呼び出しています。
// おはようロボ作成
Robot robo = new Robot(100);
// エネルギーがなくなるまであいさつ
while (robo.goodMorning()) {
System.out.println("エネルギー残:" + robo.energy);
}
例えば、おはようロボ君1号を「robo1」、2号を「robo2」として作成した時、
1号と2号でそれぞれ別のインスタンスとなるので、
1号を動かす時は「robo.」、2号を動かす時は「robo2.」として
メソッドへアクセスする必要があります。
// おはようロボ1号作成
Robot robo1 = new Robot(100);
// おはようロボ2号作成
Robot robo2 = new Robot(300);
// 1号のあいさつ
robo1.goodMorning();
// 2号のあいさつ
robo2.goodMorning();
System.out.println("1号のエネルギー残:" + robo1.energy);
System.out.println("2号のエネルギー残:" + robo2.energy);
クラス変数とは?フィールドとの違いは?
クラス変数とは、インスタンスに紐づかないフィールドのことです。
静的フィールドとも呼ばれます。
インスタンスに紐づかないとは、オブジェクトにしなくても使えるということです。
つまり、クラスをnewせずに呼び出すことができる変数です。
クラス変数の定義方法は以下です。
「static」を最初につけることでインスタンスに紐づかない
静的な変数として扱うことができます。
static 型名 クラス変数名
また、呼び出し方は以下です。インスタンス名ではなく、
クラス名に直接「.」(ドット)をつけて呼び出します。
クラス名.クラス変数名
どのように使うのか?例で見ていきましょう。
クラスRobotに総エネルギーをクラス変数として定義しました。
おはようロボ君1号、2号をそれぞれ作成する度に、
エネルギーの合計値を計算していきます。
package example;
// クラス:メイン処理実行用
public class Example {
// メイン処理
public static void main(String[] args) {
System.out.println("総エネルギー:" + Robot.energySum);
// おはようロボ1号作成
Robot robo1 = new Robot();
// 総エネルギー計算
Robot.energySum += robo1.energy;
System.out.println("1号エネルギー残:" + robo1.energy);
System.out.println("総エネルギー:" + Robot.energySum);
// おはようロボ2号作成
Robot robo2 = new Robot();
// 総エネルギー計算
Robot.energySum += robo2.energy;
System.out.println("2号エネルギー残:" + robo2.energy);
System.out.println("総エネルギー:" + Robot.energySum);
}
}
// クラス:おはようロボ
class Robot {
// フィールド:エネルギー
int energy = 100;
// クラス変数:総エネルギー
static int energySum = 0;
}
実行結果は以下です。
総エネルギー:0
1号エネルギー残:100
総エネルギー:100
2号エネルギー残:100
総エネルギー:200
インスタンスrobo1、robo2があるなしに関わらず、
クラスとして変数energySumを保持しています。
このように、フィールドは個々のインスタンスに紐づいた値、
クラス変数はクラスに紐づいた値となります。
クラス変数は、オブジェクトが持つ直接の動きや状態ではないけど、
クラスに関連する値として持っておきたい、使いたい時に定義して使います。
クラスメソッドとは?インスタンスメソッドとの違いは?
クラスメソッドとは、インスタンスに紐づかないメソッドのことです。
静的メソッドとも呼ばれます。
クラス変数と同じく、クラスをnewせずに呼び出すことができます。
クラスメソッドの定義方法は以下です。
「static」を最初につけることでインスタンスに紐づかない
静的なメソッドとして扱うことができます。
static 戻り値の型 クラスメソッド名(引数1, 引数2, …) { 処理 }
また、呼び出し方は以下です。インスタンス名ではなく、
クラス名に直接「.」(ドット)をつけて呼び出します。
クラス名.クラスメソッド名
サンプルコードは以下です。
クラスRobotの仕様を説明するメソッドをクラスメソッドとして定義しました。
package example;
// クラス:メイン処理実行用
public class Example {
// メイン処理
public static void main(String[] args) {
// おはようロボの仕様説明
Robot.aboutRobot();
}
}
// クラス:おはようロボ
class Robot {
// クラスメソッド:仕様を説明する
static void aboutRobot() {
System.out.println("説明しよう!このロボットは、なんと、\n"
+ "「おはよう」を言う為だけに開発されたロボットなのである!");
}
}
実行結果は以下です。
説明しよう!このロボットは、なんと、
「おはよう」を言う為だけに開発されたロボットなのである!
インスタンスを作成していませんが、
クラスから直接メソッドを呼び出すことができていますね!
このように、インスタンスメソッドは個々のインスタンスに紐づく動き、
クラスメソッドはクラスに紐づく処理を扱う時に定義して使います。
まとめ
Javaのクラスについて、以下説明しました。
- オブジェクトとクラス
- クラスの書き方と使い方
- インスタンスとオブジェクト
- メンバの書き方と使い方(フィールド、メソッド)
- コンストラクタの書き方と使い方
- thisの使い方
- メンバへのアクセス方法
- クラス変数とクラスメソッド
クラスを定義するという内容の中に、これだけの基本要素が含まれています。
また、Javaプログラミングにおいて、クラス定義は最も基本的な部分の1つです。
わからない部分は何度も読み返すなどして、しっかり身につけておきましょう!