手を動かして学ぶ Java入門 (クラス・フィールド)
環境構築不要! ブラウザから直接コードを実行できます。
本記事では、Java のクラス・フィールドについて学びます。
10分くらいで、さくっと終わる記事をめざしています。
シリーズ一覧
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)
続きは近日公開予定!
はじめに
この記事は paiza.IO の「Online Java compiler」を利用しています。
2024/12/17 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)
実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。
詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。
クラスのおさらい
クラスとは、本当に簡単にいうと…
- フィールド (変数)
- メソッド (関数)
この2つが集まったものです。
今回は、このうちの フィールド については学んでいきます。
フィールド
フィールドとは、クラスのインスタンスが持つ 変数 のことです。
Java 以外の言語では「メンバ変数」と呼ばれることもあります。
通常の変数については 以前の記事 でも解説しましたね。
そちらはフィールドに対して「ローカル変数」と呼ばれたりします。
さて、フィールドの特徴は、そのクラス内であれば、
- どのメソッドからでもアクセスできる
という点です。
public class Sample {
// フィールド
private int value;
public void increment() {
// アクセスOK!
value++;
}
public void print() {
// アクセスOK!
System.out.println(value);
}
}
上記の Sample クラスには value フィールドがあります。
value フィールドは、increment メソッドからも print メソッドからもアクセスできます。
それでは実際にコードを動かしてみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 「出力」のところに
value = 0
value = 1
value = 2
と表示されたら成功です。
ちなみにローカル変数は、{ ... } で囲まれた範囲からのみアクセスできます。
public class Sample {
public void increment() {
// ローカル変数
int value = 0;
// アクセスOK!
value++;
}
public void print() {
// アクセスNG (コンパイルエラー)
System.out.println("value = " + value);
}
}
上記の例では、ローカル変数の value は
- increment メソッドの { ... }
の中で宣言されています。
public class Sample {
public void increment() {
^ <--- ★ここから
int value = 0;
value++;
}
^ <--- ★ここまで
...
}
よって、ローカル変数 value は increment メソッドでのみアクセスできます。
print メソッドからはアクセスできません。(コンパイルエラーになります)
実際にコンパイルエラーになることを確認してみましょう。
コードは変更せずに、そのまま「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか?
Sample.java:12: error: cannot find symbol
System.out.println("value = " + value);
^
symbol: variable value
location: class Sample
1 error
とコンパイルエラーになれば成功です。
value というシンボル(変数) が見つかりません、という内容ですね。
宣言
フィールドを使うためには、まずクラスで宣言する必要があります。
public class Sample {
private int value; // フィールドの宣言!
...
}
フィールド宣言の基本は
- アクセス修飾子 + 変数の型 + 変数名
となります。
private int value;
^^^^^^^ <--- アクセス修飾子
private int value;
^^^ <--- 変数の型
private int value;
^^^^^ <--- 任意の変数名
これで、フィールドの宣言ができました。
初期値は指定していません。
int 型の場合は、初期値を指定しないとデフォルトで 0 になります。
次のように 初期値を指定したのと同じです。
private int value = 0;
また、0 以外にも好きな値で初期化できます。
private int value = 123;
private int value = -456;
アクセス修飾子
アクセス修飾子を使うと、
- そのフィールドをクラスの外に公開するか? 非公開にするか?
という制御ができます。
public class Sample {
private int value;
^^^^^^^ <--- フィールドのアクセス修飾子
}
フィールドのアクセス修飾子は private (非公開) にするのが一般的です。
クラスの外からアクセスしようとするとコンパイルエラーになります。
Sample sample = new Sample();
int a = sample.value; // コンパイルエラー
System.out.println(a);
実際にコンパイルエラーになることを確認してみましょう。
コードは変更せずに、そのまま「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか?
Main.java:5: error: value has private access in Sample
int a = sample.value;
^
1 error
とコンパイルエラーになれば成功です。
"value has private access in Sample" とは、意訳すると
- Sample クラスの value フィールドは private です。(よって外からはアクセスできません)
という感じです。
アクセス修飾子を public (公開) にすると外部からも直接アクセスできます。
ただし、あまり使うことはありません。
public class Sample {
public int value;
}
Sample sample = new Sample();
int a = sample.value; // コンパイルOK
System.out.println(a);
先ほどのコードを書き換えて、実際にコンパイルOKになることを確認してみましょう。
Sample クラスの
public class Sample {
private int value = 123;
}
これを…
public class Sample {
public int value = 123;
}
に書き換えてから「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 「出力」のところに
123
と表示されたら成功です。
public にしたほうが便利なのでは? と思うかたもいらっしゃるでしょう。
確かに利便性だけを考えたら public のほうがよいかもしれません。
しかし、private にすることによるメリットもあります。
それは、オブジェクト指向の「情報隠蔽」という考えかたによるものです。
ただ、そのあたりの話は本記事の主眼ではないため割愛します。
もし興味のあるかたは、以下のキーワードで検索してみてください。
- オブジェクト指向
- カプセル化
- 情報隠蔽
また、public や private 以外のアクセス修飾子については、下記の記事もご参照ください。
- 関連:アクセス修飾子の基本
インスタンス毎に独立
フィールドの大事な特徴の1つに、
- フィールドは インスタンス毎に独立 して生成される
という点があります。
具体的な例で見てみましょう。
public class Sample {
private int value;
public void increment() {
value++;
}
public void print() {
System.out.println("value = " + value);
}
}
Sample sample1 = new Sample();
Sample sample2 = new Sample();
sample1.increment();
sample1.increment();
sample2.increment();
sample1.print();
sample2.print();
Sample クラスのインスタンスを
- sample1
- sample2
と2つ生成しているのがポイントですね。
そして、
- sample1 は increment メソッドを2回
- sample2 は increment メソッドを1回
呼び出しています。
さて、結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
いかがでしたでしょうか? 「出力」のところに
value = 2
value = 1
と表示されたら成功です。
sample1 と sample2 は、それぞれ別で管理されている value フィールドを持っています。
よって、increment メソッドを呼び出しても、それぞれのインスタンスの value だけが +1 されるわけですね。
応用問題
【問題】
まずは、下記のプログラムをそのまま「実行(Ctrl-Enter)」してみましょう。
結果はコンパイルエラーになったはずです。
Rectangle クラスは、4か所 ### となっています。
public class Rectangle {
private ###
private ###
public void setWidth(int value) {
###
}
public void setHeight(int value) {
###
}
...
}
ここを正しいコードに書き換えて、プログラムを実行すると
幅 = 50, 高さ = 100
と「出力」に表示するようにしてください。
ちなみに、Rectangle は「長方形」、width は「幅」、height は「高さ」という意味です。
それでは、Rectangle クラスの4か所の ### を書き換えて「実行(Ctrl-Enter)」してみましょう。
注意:コードは2ファイルあります。上部のタブで切り替え可能です。
(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)
無事に、
幅 = 50, 高さ = 100
と出力されましたでしょうか?
もし解けなかった場合は、下記の回答例をご参照ください。
回答例
【コード】
public class Rectangle {
private int width;
private int height;
public void setWidth(int value) {
width = value;
}
public void setHeight(int value) {
height = value;
}
public void print() {
System.out.println("幅 = " + width + ", 高さ = " + height);
}
}
【出力】
幅 = 50, 高さ = 100
まとめ
フィールドとは、クラスのインスタンスが持つ変数のことです。
そのクラス内であれば、どのメソッドからでもアクセスできるのが特徴です。
クラスにはなくてはならない要素の1つですね。
次回は「手を動かして学ぶ Java入門 (クラス・コンストラクタ)」になります。
関連記事
- シリーズ
- 手を動かして学ぶ Java入門 (Hello world 編)
- 手を動かして学ぶ Java入門 (数値と演算)
- 手を動かして学ぶ Java入門 (数値と変数)
- 手を動かして学ぶ Java入門 (コメントの書き方)
- 手を動かして学ぶ Java入門 (文と式の違い)
- 手を動かして学ぶ Java入門 (if文)
- 手を動かして学ぶ Java入門 (if-else文、if-elseif文)
- 手を動かして学ぶ Java入門 (文字列の連結)
- 手を動かして学ぶ Java入門 (while文)
- 手を動かして学ぶ Java入門 (break文)
- 手を動かして学ぶ Java入門 (continue文)
- 手を動かして学ぶ Java入門 (for文)
- 手を動かして学ぶ Java入門 (クラスの超基本)
- 手を動かして学ぶ Java入門 (クラス・メソッド)
- 手を動かして学ぶ Java入門 (クラス・フィールド)
- 手を動かして学ぶ Java入門 (クラス・コンストラクタ)
- 手を動かして学ぶ Java入門 (文字列クラス)
- 手を動かして学ぶ Java入門 (静的メソッド)
- 手を動かして学ぶ Java入門 (静的フィールド)
- 手を動かして学ぶ Java入門 (定数の定義)
- 手を動かして学ぶ Java入門 (クラス継承の超基本)
- 手を動かして学ぶ Java入門 (メソッドのオーバーライド)
- 手を動かして学ぶ Java入門 (メソッドのオーバーロード)