■クラス・フィールド変数
はじめに
この章では、javaの基本的な構造を学んでもらいます。
ソースを読むにしても、書くにしてもとーっても大切なポイントになります。
とは言っても、最初は難しいと思います。
ひとまず、読み進めていきましょう!
Step1: クラス
クラスとは、「 データ 」と「 処理 」の集まりです。
Javaのプログラムはこの「クラス」を複数組み合わせてプログラミングしていきます。
そのため、Javaのプログラミングは、大きく分けて2つの作業に分かれます。
クラスをプログラミング
クラスには「データ」と「処理」を記述します。
- ・データ
- そのクラスが持つ特徴・クラスに見合った情報などを指します
- ・処理
- そのクラス内で行いたいタスク・TODO・ふるまいなどを指します
呼び出し側のプログラミング
クラスが完成したら、クラスのインスタンス(実体)を生成し、メソッドの呼び出しを記述します。
メソッドの呼び出しは、クラス内、または、クラスの呼び出し側の両方で行えます。
クラスをプログラミングするにはいくつかルールがあります。
1. 必ず public class クラス
と記述
2. { }
(中括弧)で囲むように 「データ」 と 「処理」 を記述
このように中括弧で囲まれたプログラムコードのまとまりを ブロック と呼びます。
サンプルクラス 「HelloJava.java」
// クラス public class HelloJava { // フィールド private String message; // コンストラクタ public HelloJava() { message = "Hello, Java!"; } // メソッド public void print() { System.out.println(message); } }
解説①
クラス名には、オリジナルの名前を記述することが可能ですが、
Javaではクラス名の最初の一文字は半角英大文字で記述するという慣習があります。
上記のプログラムでは、クラスに HelloJava
という名前を付けています。
解説②
クラスのブロック内に、 データ(フィールド変数) を宣言したり、
処理(コンストラクタやメソッド) のブロックを記述したりしていきます。
上記のプログラムでは、 message
という名前のStringクラスのフィールドを宣言しています。
また、コンストラクタ HelloJava()
と、メソッド print()
を定義しています。
Step2: mainメソッド
プログラミングしたクラスを動かすため、自クラス又は他のクラス内に mainメソッド
を記述します。
そのmainメソッドの中で「 new
」演算子を使用し、メモリ上にクラスが扱うデータ用の領域を新規に確保します。
このようにして クラス という 「型」 から 「具体的な実体」 を生成することを インスタンス化 と呼び、
生成されたものを インスタンス と呼びます。
// プログラムを実行するためのクラス(mainメソッドを持つクラス) public class Main { // mainメソッド public static void main(String[] args) { // HelloJavaクラスのインスタンスを生成して、HelloJavaクラス型の変数hjに保持する HelloJava hj = new HelloJava(); // 生成したインスタンスより、HelloJavaクラスのprintメソッドを呼び出す hj.print(); } }
【実行結果】
Hello, Java!
Step3: フィールド変数
フィールドまたは フィールド変数 とは、クラス内の 変数 のことです。
フィールドを宣言するとき、「 public
」や「 private
」などの アクセス修飾子 を記述します。
アクセス修飾子は、省略することも可能です。
フィールドとして宣言した変数は、コンストラクタやメソッド内で変数を宣言することなく、
そのクラス内であればどこからでも値を参照したり更新したりすることができます。
public class HelloJava { // Stringクラスの、messageという名前のフィールド。 // アクセス修飾子が「private」なので、このHelloJavaクラス内でのみ使用可能。 private String message; ... }
また、 フィールドは、初期化を省略してもかまいません。 その場合は、デフォルト値が入ります。
Step4 : アクセス修飾子
アクセス修飾子とは、「public」
、「protected」
、「private」
といった
修飾子(変数名、関数名の前に付与する単語)のことで、 クラスや変数がどこからアクセス可能であるかの公開範囲 を決定します。
アクセス修飾子 | 概要 |
---|---|
public | すべてのクラスからアクセスできる |
protected | 現在のクラスとサブクラスからアクセスできる |
なし | 現在のクラスと同じパッケージのクラスからアクセスできる |
private | 現在のクラスからだけアクセスできる |
例えば、以下のようなコードがあったとします。
ModAccess.java
package com.example.mynavi.modifier; public class ModAccess { public String pub_var = "publicだよ"; protected String prot_var = "protectedだよ"; String pack_var = "package privateだよ"; private String pri_var = "privateだよ"; public void test() { // クラス内部ではすべてのレベルのメンバーにアクセス可 System.out.println(this.pub_var); System.out.println(this.prot_var); System.out.println(this.pack_var); System.out.println(this.pri_var); } public static void main(String[] args) { ModAccess m = new ModAccess(); m.test(); } }
クラスで定義したアクセス修飾子を同一クラスから呼んだ場合は
どのアクセス修飾子にも問題なくアクセスできます。
【出力結果】
publicだよ protectedだよ package privateだよ privateだよ
ModAccess.javaに書かれている変数を別のファイル(ModAccess.javaを継承)から呼んだ場合はどうでしょうか?
ModAccessChild.java
package com.example.mynavi.modifier; // ModAccessのサブクラス public class ModAccessChild extends ModAccess { public void test() { System.out.println(this.pub_var); System.out.println(this.prot_var); System.out.println(this.pack_var); // System.out.println(this.pri_var); ←プライベート変数にはアクセス不可 } public static void main(String[] args) { ModAccess mc = new ModAccessChild(); mc.test(); } }
【出力結果】
publicだよ protectedだよ package privateだよ
解説
ModAccess.javaを継承している( extends ModAccess
の部分)ので、
private
以外は出力できています!
また、 private
な pri_var
にはアクセスができないため、
実装時にはコンパイルエラーとなりエラー対象のコードに赤い下線が引かれます。
ポイント
コンパイルエラー時の対応策としては主に以下の3つとなります。
- 正しいコードに修正
- コメントアウト(
//
)することにより、コードとして認識させない - 対象のコードを削除
アクセス修飾子のみでコンパイルエラーが発生する訳ではありませんので、
その他の実装でコンパイルエラーが発生した場合は上記3つの対応を参考にエラーを回解消しましょう!
最後に、ModAccess.java
に書かれている変数を
別のファイル(継承とかはしていない)から呼んだ場合はどうでしょうか?
ModAccessOther.java
package com.example.mynavi.other; import com.example.mynavi.modifier.ModAccess; // ModAccessと継承関係のない他パッケージのクラス public class ModAccessOther { public static void main(String[] args) { ModAccess my = new ModAccess(); System.out.println(my.pub_var); // protected以下のメンバーにはアクセス不可 // System.out.println(my.prot_var); // System.out.println(my.pack_var); // System.out.println(my.pri_var); } }
このコードを実行すると下のように出力されます↓↓↓↓
継承をしていないので、public
以外は出力できません!
【出力結果】
publicだよ