アクセス指定子
メンバへのアクセスの許可
第6日目では、クラスおよびインスタンスの生成について説明しました。ここでは、さらにその内容を深めていこうとしていくことにします。クラスには、フィールドおよび、メソッドと呼ばれるものがあることはすでに説明しました。
このフィールドおよびメソッドには、アクセス許可を指定することにより、アクセスできる範囲を指定することができます。そのために必要なのが、アクセス指定子です。ここでは、アクセス指定子を利用して、メンバの可視性を指定する方法について説明します。
サンプルプログラム
以下のプログラムを実行してみてください。
SampleClass02.java
package day7;
public class SampleClass02 {
// コンストラクタ
public SampleClass02(){
System.out.println("コンストラクタ");
}
// privateメソッド
private void method1(){
System.out.println("method1(private)");
}
// publicメソッド①
public void method2(){
System.out.println("method2(public)");
}
// publicメソッド②
public void method3(){
// privateメソッドの呼び出し
method1();
System.out.println("method3(public) : num=" + this.num);
}
// privateフィールド
private int num = 1;
}
package day7;
public class Sample701 {
public static void main(String[] args) {
SampleClass02 s = new SampleClass02();
// method1()は、privateなので、外部からはアクセスできない。
//s.method1();
// method2呼び出し
s.method2();
// method3呼び出し
s.method3();
//numは、privateフィールドなので、外部からはアクセスできない。
//s.num = 1;
}
}
method2(public)
method1(private)
method3(public) : num=1
SampleClass02のメンバの先頭に、public、privateなどといった文字が書かれています。これが、アクセス修飾子(しゅうしょくし)です。
アクセス修飾子の種類
すでに説明したとおり、アクセス修飾子は、フィールドおよびメソッドへのアクセスの制限を指定します。Javaのアクセス修飾子は、以下のようなものがあります。(表7-1)
表7-1.Javaのアクセス指定子| アクセス指定子 | 呼び名 | 意味 |
|---|---|---|
| public | パブリック | どこからでも呼び出せる。 |
| (default) | デフォルト | アクセス指定子が省略されている場合。同じパッケージ内からしか呼び出せない。 |
| protected | プロテクティッド | 同じパッケージか、そのサブクラスからしか呼び出せない。 |
| private | プライベート | 同じクラス内からしか呼び出せない。 |
この第6日目のサンプルでは、アクセス修飾子が省略されています。そのため、デフォルトであり、同一パッケージないからのアクセスが可能です。ここでは、publicおよび、privateが使われています。
サンプルの解説
以上を踏まえて、サンプルの解説をしてききます。SampleClass02において、method2()および、mehtod3()は、publicなので、外部のクラスである、Sample701.javaからアクセス可能なので、10行目および12行目でアクセスしています。
しかし、メソッドmethod1()および、フィールドnumには、privateがついているので、クラスの外からアクセスできません。8行目および14行目のコメントを外すと、以下のようなエラーメッセージが出ます。
privateのメンバに外部からアクセスした場合のエラーメソッド method1() は型 SampleClass02 で不可視です
フィールド SampleClass02.num は不可視です
at day7.Sample701.main(Sample701.java:8)
しかし、SampleClass02.javaの20行目および、21行目では、method1()および、numにアクセスしています。ここでエラーが出ないのは、同一クラス内だからです
クラスの可視性
また、クラスの先頭に、publicがついていますが、このように、クラス全体の可視性を指定することも可能です。ただ、クラスの場合、指定できる可視性は、publicおよび、デフォルトだけです。publicで指定したクラスは、他のパッケージからアクセスすることができ、デフォルトのクラスは、同一パッケージ内からしかアクセス出来ません。
コンストラクタ
クラス名と同一の名前のメソッド
ところで、SampleClass02.javaの6行目に、クラス名と同一のメソッドがあります。これを、コンストラクタと言います。コンストラクタは、戻り値の指定がありません。そして、特徴としては、インスタンス生成時に、一度だけ呼び出されるという特殊なメソッドです。
実は、インスタンス生成時に、newの後にクラス名を指定しているのは、実はこの、コンストラクタを呼び出していたのです。
コンストラクタの呼び出しカプセル化
サンプルプログラム
Java言語でのプログラムの慣例として、通常フィールドは、privateで隠蔽し、外部からアクセスするメソッドを介して値の変更・取得を行います。これを、カプセル化と言います。以下にサンプルを示しますので、まずは実行してみてください。
SampleClass03.java
package day7;
public class SampleClass03 {
// int型のフィールド(privateで隠ぺいされている)
private int number = 0;
// String型のフィールド(privateで隠されている)
private String str = "";
// コンストラクタ(引数つき)
public SampleClass03(String str){
this.str = str;
}
// number変数のセッター
public void setNumber(int number){
this.number = number;
}
// number変数のゲッター
public int getNumber(){
return this.number;
}
// str変数のゲッター
public String getStr(){
return this.str;
}
}
package day7;
public class Sample702 {
public static void main(String[] args) {
// 引数つきコンストラクタの呼び出し
SampleClass03 s = new SampleClass03("HelloWorld.");
// SampleClass03 s = new SampleClass03();
// numberのセッターで、値を設定
s.setNumber(100);
// ゲッターで値を呼び出し、内容を表示
System.out.println(s.getNumber());
System.out.println(s.getStr());
}
}
HelloWorld.
セッターとゲッター
SampleClass03.javaを見てもわかる通り、フィールドnumberおよびstrは、privateで隠ぺいされており、外部からアクセスすることはできません。privateで隠ぺいされたフィールドに値を書き込むメソッドを、セッター、値を取得するメソッドのことを、ゲッターと呼びます。(表7-2、図7-1参照)
表7-2.参照| フィールド名 | セッター | ゲッター |
|---|---|---|
| number | void setNumber(int number) | int getNumber() |
| str | - | String getStr() |
![]() |
セッターは、setの後に、変数名がきます。この場合、最初の文字が大文字になる(number→Numberのように)になるのが通例です。ゲッターについても同様です。セッターの引数は、また、決まりではありませんが、セッターの引数に指定する変数は、フィールドと同じ名前を付けるケースが多いようです。
また、表からわかるとおり、一つのフィールドに対し、必ずしもセッターとゲッターが両方つくとは限りません。必要に応じ、セッターのみ、あるいはゲッターのみの場合もあります。
引数つきのコンストラクタ
SampleClass03.javaの9行目から11行目に、SampleClass03クラスのコンストラクタが定義されています。このコンストラクタには、引数が付いています。このように、コンストラクタは、他のメソッド同様、引数をつけることが可能です。このように、コンストラクタは、引数がついたものを指定することも可能です。このようなコンストラクタを使用する場合には、newをするときにも、引数を与える必要があります。
引数付きコンストラクタと、newの指定の方法↓
SampleClass03 s = new SampleClass03("HelloWorld."); ← 呼び出し方
クラスに、引数つきのコンストラクタが定義されている場合、引数なしのコンストラクタを呼び出すことはできません。ためしに、Sample702.javaの8行目のコメントを削除してください。次のようなエラーが出ます。
重複ローカル変数 s
コンストラクター SampleClass03() は未定義です
at day7.Sample702.main(Sample702.java:8)
これは、引数なしのコンストラクタが定義されていないという意味です。
デフォルトコンストラクタ
ところで、第6日目で紹介した、Sample01.javaには、コンストラクタがありませんでした。クラスにコンストラクタが存在しないのに、どうしてコンストラクタが呼び出せるのでしょうか?
SampleClass01.java(再掲)
package day6;
public class SampleClass01 {
// フィールド
int n = 10;
String s = "field";
// メソッド
int add(int a,int b){
return a + b;
}
String add(String s){
return this.s + s;
}
void showNum(){
System.out.println("n = " + n);
}
}
実は、このような場合、Javaでは、デフォルトコンストラクタと呼ばれる、見えないコンストラクタがあると考えます。このコンストラクタないでは、何も処理はされませんが、newで呼び出すのは、このコンストラクタであるというのが、Javaの考え方です。
図7-2.デフォルトコンストラクタ![]() |
練習問題 : 問題5.











