広告

手を動かして学ぶ Java入門 (クラス・フィールド)

環境構築不要! ブラウザから直接コードを実行できます。
本記事では、Java のクラス・フィールドについて学びます。

10分くらいで、さくっと終わる記事をめざしています。


シリーズ一覧

続きは近日公開予定!

はじめに

この記事は paiza.IO の「Online Java compiler」を利用しています。
2024/10/21 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)

実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。

詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。

クラスのおさらい

オブジェクト指向プログラミングにおけるクラス(英: class)は、オブジェクトを生成するための設計図あるいはひな形に相当するものである。抽象データ型の一つ。クラスから生成したオブジェクトの実体のことをインスタンスという。

クラスイメージ図

クラスとは、本当に簡単にいうと…

  • フィールド (変数)
  • メソッド (関数)

この2つが集まったものです。

今回は、このうちの フィールド については学んでいきます。

フィールド

オブジェクト指向プログラミングでは、フィールドはクラスや構造体などに直接宣言される任意の型の変数であり[3]、オブジェクト内にカプセル化されたデータである。

フィールドとは、クラスのインスタンスが持つ 変数 のことです。
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++;
    }
    ^ <--- ★ここまで

    ...
}

よって、ローカル変数 valueincrement メソッドでのみアクセスできます。
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;

アクセス修飾子

カプセル化と情報隠蔽を実現するために、Javaではアクセス修飾子を使います。
アクセス修飾子(publicやprivateなど)を使うと、クラスのメンバをどこまで公開するか?どこまで非公開にするか?を制御できます。

アクセス修飾子を使うと、

  • そのフィールドをクラスの外に公開するか? 非公開にするか?

という制御ができます。

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 にすることによるメリットもあります。
それは、オブジェクト指向の「情報隠蔽」という考えかたによるものです。

ただ、そのあたりの話は本記事の主眼ではないため割愛します。

もし興味のあるかたは、以下のキーワードで検索してみてください。

  • オブジェクト指向
  • カプセル化
  • 情報隠蔽

また、publicprivate 以外のアクセス修飾子については、下記の記事もご参照ください。


インスタンス毎に独立

フィールドの大事な特徴の1つに、

  • フィールドは インスタンス毎に独立 して生成される

という点があります。

具体的な例で見てみましょう。

public class Sample {
    private int value;

    public void increment() {
        value++;
    }

    public void getValue() {
        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つ生成しているのがポイントですね。

そして、

  • sample1increment メソッドを2回
  • sample2increment メソッドを1回

呼び出しています。

さて、結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

value = 2
value = 1

と表示されたら成功です。

sample1sample2 は、それぞれ別で管理されている value フィールドを持っています。
よって、increment メソッドを呼び出しても、それぞれのインスタンスの value だけが +1 されるわけですね。

イメージ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つですね。

それでは次回もお楽しみに!


関連記事

ページの先頭へ