サンプルプログラム


ローカル変数とクラス変数

ソースプログラム
1: class Demo {
2:     int a;
3:     void Demo1() {
4:       int x;
5:       …
6:     }
7:     vod Demo2() {
8:       int x;
9:       …
10:    }
11:  }

考察
・ローカル変数 = メソッド内部で宣言した変数
・クラス変数 = メソッドの外部で宣言した変数
・C言語の変数のスコープを参照せよ

ローカル変数とクラス変数

1からnまでを表示するプログラム
1: classs Display {
2:     int n                                      // クラス変数
3:     void Disp() {
4:       int i;                                   // ローカル変数
5:       for (i = 1; i <= n; i++)
6:         System.out.print(I + " ");
7:     }
8:
9:   class VarSample {
10:    public static void main(String args[]) {
11:      Display obj = new Display();             // クラスDisplayのオブジェクトobj生成
12:      obj.n = 15;                              // オブジェクトobjの変数nに15を代入
13:      obj.Disp();                              // オブジェクトobjのDisp()実行
14:    }
15:  }

実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

考察
・変数 n はクラス変数
・メソッドDisp()内のiはローカル変数であるが、メモリ領域は別

static変数

異なるオブジェクト間の変数合計プログラム
1: class Sum {
2:     int total;
3:     Sum() {                              // コンストラクタ(クラス名と同名)
4:       total = 0;                         // 0 クリア
5:     }
6:     void add(int x) {
7:       total += x;
8:     }
9:   }
10:  
11:  class SumSample {
12:    public static void main(String args[]) {
13:      Sum obj1 = new Sum();              // クラスSumのオブジェクトobj1生成
14:      Sum obj2 = new Sum();              // クラスSumのオブジェクトobj2生成
15:      obj1.add(10);
16:      obj1.add(20);
17:      obj2.add(30);
18:      obj2.add(40);
19:      System.out.println("obj1.total = " + obj1.total);
20:      System.out.println("obj2.total = " + obj2.total);
21:    }
22:  }

実行結果
obj1.total = 30
obj2.total = 70

考察
・同一クラスのオブジェクトを複数作成した場合、それぞれのオブジェクトで参照する変数の値は異なる
・オブジェクトobj1の変数totalとオブジェクトobj2の変数totalは異なる。メモリ領域が異なる(変数のスコープ

コンストラクタ

コンストラクタを用いた合計プログラム
1: class Sum {
2:     int total;
3:     Sum() {                              // コンストラクタ 引数無し
4:       total = 0;
5:     }
6:     Sum(int x) {                         // コンストラクタ 引数 x
7:       total = x;
8:     }
9:     void add(int x) {
10:      total += x;
11:    }
12:  }
13:  
14:  class ConstrcSample {
15:    public static void main(String args[]) {
16:      Sum obj1 = new Sum();              // クラスSumのオブジェクトobj1生成
17:      obj1.add(10);
18:      obj1.add(20);
19:      System.out.println("sum1 = " + obj1.total);
20:      Sum obj2 = new Sum(100);           // クラスSumのオブジェクトobj2生成
21:      obj2.add(10);
22:      obj2.add(20);
23:      System.out.println("sum2 = " + obj2.total);
24:    }
25:  }

実行結果
sum1 = 30
sum2 = 130

考察
・クラス名と同じ名前のメソッドをコンストラクタという。
・コンストラクタはオブジェクトの初期化処理に利用できる。
・コンストラクタに引数を用いたり、オーバーロード(同じ名前で引数が異なる定義)することができるが、返し値をもつことはできない。

staticイニシャライズ

staticイニシャライズを行ったプログラム
1: class Disp {
2:     static {                             // static イニシャライズ
3:         System.out.println("initialize");
4:     }
5:    Disp() {                             // コンストラクタ
6:         System.out.println("construct");
7:     }
8:   }
9:  
10:  class StaticSample {
11:    public static void main(String args[]) {
12:      Disp obj1 = new Disp();            // オブジェクト生成時にコンストラクタを処理
13:      Disp obj2 = new Disp();            // オブジェクト生成時にコンストラクタを処理
14:    }
15:  }

実行結果
initialize     ※ Dispクラスのロード時に処理
construct      ※ Disp.obj1 = new Disp(); が実行されるときに処理
construct      ※ Disp.obj2 = new Disp(); が実行されるときに処理

考察
・staticイニシャライズは、クラスが呼ばれた(ロードされた)ときに自動的に実行される。
・コンストラクタよりも早く処理したい場合や、一度だけ処理を行いたい場合などに用いる。

メソッドのオーバーロード

メソッドのオーバーロードを行ったプログラム
1: class Display {
2:     void Disp() {                          // メソッド Disp 引数なし
3:         System.out.println("Nothing");
4:     }
5:     void Disp(int x) {                     // メソッド Disp 引数 x
6:         System.out.println(x);
7:     }
8:     void Disp(int x, int y) {              // メソッド Disp 引数 x, y
9:         System.out.println(x + y);
10:    }
11:  }
12: 
13:  class OvldSample {
14:    public static void main(String args[]) {
15:      Display obj = new Display();    // クラスDisplayのオブジェクトobj生成
16:      obj.Disp();                     // オブジェクトobjのDisp()を実行
17:      obj.Disp(1);                    // オブジェクトobjのDisp(1)を実行
18:      obj.Disp(1, 2);                 // オブジェクトobjのDisp(1,2)を実行
19:    }
20:  }

実行結果
Noting
1
3

考察
・メソッドのオーバーロードとは、クラス内に同じ名前のメソッドを定義すること。
・メソッドのオーバーロードを行う場合は、引数の数や型が異なっていなければならない。







オリジナルプログラム


問題1

ソースプログラム
1:  class rep {                                           //クラスを定義
2:            static int y;                               //値yを共有させる
3:            private int i = 200;                        //このクラス内のメソッドだけint iは200
4:            static{                                     //共有させる
5:          System.out.println("static イニシャライズ");  //出力する
6:      }
7:            int add(int x) {                            //メソッドaddを定義
8:                return x + y;                           //x+yを返す
9:      }
10:           void Over(){                                //メソッドのオーバーロード
11:         System.out.print(" 3 + 5 = ");                //3+5を出力
12:     }
13:           void Over(int z){                           //メソッドのオーバーロードただし、引数が有る
14:         System.out.println(z);                        //zを出力
15:     }
16:           rep(){                                      //コンストラクタを行う
17:         System.out.println("コンストラクタ");         //出力する
18:     }
19: }
20:
21:     public class original {                             //クラスを定義する
22:      public static void main(String args[]) {         //決まり文句
23:         int a, wa;                                    //a、waを定数
24                  rep enzan1 = new rep();              //文字列を代入
25:                  rep enzan2 = new rep();              //文字列を代入
26: 
27:                  a = 45;                              //aは45
28:                  enzan1.y = 20;                       //enzan1.yは20
29:                  wa = enzan1.add(a);                  //waはenzan1のadd(a)
30:                  System.out.println(" a + b = " + wa);//出力する
31:
32:                  enzan2.y += 15;                      //enzan2のyに15足す
33:                  System.out.println(" y = " + rep.y); //出力する
34:
35:                  enzan1.Over();                       //メソッドのオーバーロードの実行
36:                  enzan1.Over(8);                      //メソッドのオーバーロードの実行
37: 
38:                  //System.out.println(" i = " + enzan1.i);//出力出来ない
39:     }
40: }

実行結果
[nw0523:~] j05023% javac original.java
[nw0523:~] j05023% java original
static イニシャライズ
コタストラクタ
コタストラクタ
 a + b = 65
 y = 35
 3 + 5 = 8

考察
2行目: メソッドの外部で宣言した変数をクラス変数という。またメソッドの内部で宣言した変数をローカル変数という。またstatic変数は値を共有させる。

3行目: privateはアクセス制御であり詳しくは下方に表を示す。

4行目: これはstaticイニシャライズという。これはクラスが呼ばれたときに一度だけ自動に実行される。

7行目: メソッドaddを定義している。

8行目: 「x + y」の結果を返す。

10行目: メソッドのオーバーロードである。これは同じクラス内に同じメソッドを定義するということ。同じメソッドであっても引数の数や型は異なって
       いなければならない。

13行目: 13行目のオーバーロードであるが、これには引数があるので異なっている。

16行目: クラスメイト同じ名前のメソッドをコンストラクタという。オブジェクトの初期化処理に利用できる。

24行目: クラスKeisanのオブジェクト、enzan1の生成を行っている。またここでstaticイニシャライズが実行される。

25行目: ここでも16行目と同じenzan2の生成をしているが、staticイニシャライズは実行されない。

28行目: オブジェクトenzan1の変数yに値を入れている。

29行目: オブジェクトenzan1のメソッドaddを呼び、aの値を代入している。また返り値をwaに格納。

32行目: オブジェクトenzan2の変数yに10を足している。static変数であるから、enzan1のyに15足しているのと同じであるから、出力すると35となる。

33行目: 違うクラスの変数を出力する場合は「クラス名.変数」と記述する。

35行目: メソッドのオーバーロードの実行。括弧内に何もないので7行目の実行となる。

36行目: メソッドのオーバーロードの実行。括弧内に数字があるので10行目の実行となる。

38行目: private変数なので参照不可となる。

アクセス制御説明
public全てのオブジェクトの全てのメソッドからアクセス可能
private定義されたクラス内のメソッドからだけアクセス可能
protected定義されたクラス内のメソッド、そのクラスから派生したサブクラス、
同一パッケージ内のクラスからアクセス可能


感想


参考文献・ページ



もどる