修飾子 | 有効範囲 |
---|---|
public | 制限なし |
protected | 同一パッケージ・サブクラスのみアクセス可能 |
デフォルト(記述なし) | 同一パッケージのみアクセス可能 |
private | クラス内のみアクセス可能 |
protectedのサブクラスというのは継承の回で話すとしてprivate以外のアクセス修飾子はパッケージ内のみ有効という項目が共通しているのであまりこだわらくてもいいかもです。
■特殊な修飾子
プログラム言語で修飾子を差すのは上記のほかにstaicやfinalのような呼び出し方法を特殊にする修飾子があります。
修飾子 | 説明 | クラス | メソッド | 変数 |
---|---|---|---|---|
static | 静的オブジェクトを生成する | ○ | ○ | ○ |
final | 定数 | ○ | ○ | ○ |
abstract | 抽象オブジェクト | ○ | ○ | × |
native | 別の言語での記述を可能にする | × | ○ | × |
synchronized | マルチスレッド用修飾子 | × | ○ | × |
volatile | マルチスレッドでの値を制御する | × | × | ○ |
nativeの説明にある別言語の代表的な言語にC言語・C++があり、native修飾子のついたメソッドはこれらの文法に沿って記述する。
つまり、「途中から別の言語で書きたい」という要望にこたえた修飾子なので冷静に考えて途中から言語体系が変わると修正がわかりづらいことになるのでまず使わない修飾子です。
「synchronized」「volatile」はマルチスレッドにおける排他制御をそれぞれのオブジェクトで行うものでスレッド利用したプログラム以外ではひつようのない修飾子です。
そして上から3つの修飾子はおそらく利用頻度の高い修飾子なので「abstract」は継承の後の抽象クラスのときにまわして残り2つを今回は解説します。
■static 修飾子
表の説明では「静的オブジェクト」と表記しましたが、具体的には静的メソッドや静的変数のことを差します。staticが付くとそのオブジェクトの格納メモリが共通メモリになり、通常の呼び出しと異なる。
public class ClassStatic {
String name;
static String tell;
public void show() {
System.out.println(name);
}
public static void showStatic(){
System.out.print(tell);
}
}
public class ActStatic {
public static void main(String [] agr) {
ClassStatic cs = new ClassStatic();//通常ならこれで実行できる
cs.name = "情報太郎";
cs.show();
/*static が付いているオブジェクトに上記のように記述するとコンパイルエラーになるため下のよう記述する*/
ClassStatic.tell = "090-xxx-xxx";
ClassStatic.showStatic();
}
--------------
†実行結果†
--------------
情報太郎
090-xxx-xxx
--------------
つまりstaticなオブジェクトの呼び出しは クラス名.メソッド名; クラス名.変数; で呼び出す。
インスタンス化がいらない半面クラス内で通常のオブジェクトを呼び出すときもこの形式で記述しなければならない。
ということで便利かどうか微妙な修飾子だが、実際「static」で定義されているJavaAPIもあり代表的なのが
- Mathクラス :乱数や四捨五入などの数学計算関連のクラス
- Calenderクラス :日付操作のクラス
- mainメソッド :多くの人はこれでstaticを知ったはず。
ちなみに…表ではクラスにも○が付いているが内部クラスとしてクラス宣言したときにしか使用できない(しかも実際つけてみても振る舞いが同じ(笑) )
ので無視してもかまわない。
■final 修飾子
定数の言葉通りこのオブジェクト(変数のほうがつかいやすい)は値が変化しません。これを厳格に再現するために下記のことができません
- 継承
- オーバーライド
- 変数に値を代入する
・メソッドを再定義するのがオーバーライドなので内容が書き換わることをするのを禁止
・継承の機能の一部に追加定義があるみたいで全体的にクラスの定義をいじることになるので禁止
みたいなことらしい…
定数の利点は特殊文字を変数化(例:final String tab = "\t";)することができ出力がラク。
■サンプル
static を利用した入力クラス
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
/*staticメソッドをもつクラス*/
public class KeyInput {
/*入力フォーマット*/
public static String input() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try{
return br.readLine();
} catch(IOException ex){
System.out.println(ex.getMessage());
return null;
}
}
/*整数値用入力メソッド*/
public static int intInput(){
int num; //返却用変数
try{
num = Integer.parseInt(input());
}catch(NumberFormatException ex) {
System.out.println(ex.getMessage());
return intInput();
}
return num;
}
/*実数値用入力メソッド*/
public static double doubleInput() {
double dnum; //返却用変数
try{
dnum = Double.parseDouble(input());
}catch(NumberFormatException ex){
System.out.println(ex.getMessage());
return doubleInput();
}
return dnum;
}
/*日付入力用メソッド*/
public static Date DateInput() {
Date day; //返却用変数
try{
day = DateFormat.getDateInstance().parse(input());
} catch(ParseException ex){
System.out.println(ex.getMessage());
return DateInput();
}
return day;
}
}
使用方法
public class EchoBack {
public static void main(String [] arg ){
final String tab = "\t";
String str = KeyInput.input();
int num = KeyInput.intInput();
System.out.println(str + tab + num);
}
}
これで例外処理が発生してもループなしで再入力できるし(メソッドを永遠に呼び出すループにはなる)mainメソッドでは例外処理を一切していません。
入力オブジェクトとしてパッケージ化すれば、インスタンスなしでどのクラスからも呼び出せて便利です。
■最後に・・・
表以外の修飾子も捜せばいろいろあるみたいですが、なぜ触れなかったというとあまり有効性がない(具体的にはjavaでやる必要がない)ものばかりという件で除外した。
残りは実装や抽象クラスをやらなければ意味不明なものですから後回しにした
使用方法
public class EchoBack {
public static void main(String [] arg ){
final String tab = "\t";
String str = KeyInput.input();
int num = KeyInput.intInput();
System.out.println(str + tab + num);
}
}
これで例外処理が発生してもループなしで再入力できるし(メソッドを永遠に呼び出すループにはなる)mainメソッドでは例外処理を一切していません。
入力オブジェクトとしてパッケージ化すれば、インスタンスなしでどのクラスからも呼び出せて便利です。
■最後に・・・
表以外の修飾子も捜せばいろいろあるみたいですが、なぜ触れなかったというとあまり有効性がない(具体的にはjavaでやる必要がない)ものばかりという件で除外した。
残りは実装や抽象クラスをやらなければ意味不明なものですから後回しにした