Report5
		day :2003/12/10
		ID  :035740F
		Name:根保光秀
		!!!  This Page Is Made By Shift JIS  !!!



   
    report5:講義資料オブジェクト指向プログラムJavaI&JavaIIの中のサンプルプログラム
        について考察せよ{〜12/15(Mon)}
                講義資料サンプルプログラムの考察については、
                ローカル変数以降interfaceまでとする。
   



もくじ

色々な変数

色々なメソッド&アクセス

継承

感想&反省










1.色々な変数






変数には次のようなものがある。

変数名
説明
クラス変数 クラス内で宣言される変数
クラス内であればどこからでも参照できる変数でメソッド等から独立しています
static宣言されてないクラス変数のことをインスタンス変数ともいいます。
ローカル変数 メソッド内で宣言される変数
宣言されたメソッド内でしか参照できない変数です。
static変数 staticな変数。
インスタンス変数をstatic宣言した変数です。
メモリの場所が一か所な変数です。
メモリの場所が固定されているので、どこから呼び出されてもいつも同じ変数です
簡単にいうと、最近流行の『共有』できる変数です。


○プログラム

[j03040:prgm/java/rep#5] j03040% java List rep5.java
File name:rep5.java
 1:/*
 2: * day: 2003/12/10
 3: *
 4: * @author j03040
 5: * @St-ID  035740F
 6: */
 7:class hen{
 8:     int Cno;            //インスタンス(クラス)変数宣言
 9:     static int SCno;  //static変数宣言
 10:    hen(){
 11:            Cno=0;
 12:            SCno=0;
 13:    }
 14:    void aaa(int x){
 15:            int Rno=0;      //ローカル変数
 16:            Cno +=x;        //Cno=Cno+x
 17:            SCno +=x;       //SCno=SCno+x
 18:            Rno =Cno+SCno;
 19:            System.out.println(Rno);
 20:    }
 21:}
 22:public class rep5 {
 23:    public static void main(String[] args) {
 24:            hen obj1= new hen();
 25:            hen obj2= new hen();
 26:            obj1.aaa(1);        
 27:            obj1.aaa(20);    
 28:            obj2.aaa(30);        
 29:            obj2.aaa(3);
 30:            System.out.println("obj1.Cno="+obj1.Cno);
 31:            System.out.println("obj1.SCno="+obj1.SCno);
 32:            //System.out.println("obj1.Rno="+obj1.Rno); Rnoはローカル変数だから参照できない
 33:            System.out.println("obj2.Cno="+obj2.Cno);
 34:            System.out.println("obj2.SCno="+obj2.SCno);
 35:            //System.out.println("obj2.Rno="+obj2.Rno);  Rnoはローカル変数だから参照できない
 36:    }
 37:}


○実行結果

[Mi:prgm/java/rep#5] j03040% java rep5
obj1.Cno=21     (1)
obj1.SCno=54    (3)
obj2.Cno=33     (2)
obj2.SCno=54    (3)


考察
○実行結果から各変数の動きを見てみる

(1)では、
一回目 x=1→Cno=1 二回目 x=20→Cno=1+20=21


(2)では、
三回目 x=30→Cno=30 四回目 x=3→Cno=30+3=33


(3)は、static変数なので少し特別で
一回目 x=1→SCno=1 二回目 x=20→SCno=1+20=21
ここからが特別で、(1)や(2)ではCnoは名前は同じだけど、それぞれ違うメモリに保存されていたので
値が違っている(別の変数といっても良い)。
だけどSCnoは上記のようにstatic変数のため同じメモリに保存されるから
obj1のSCno、obj2のSCnoなどのように区別されない(SCnoは一つだけ)つまりSCnoは
obj1とobj2で『共有』しているので、
三回目 x=30→SCno=30+21=51 四回目 x=3→SCno=3+51=54
となる。

考察2
public static void main(String[] args) {
 24:            hen obj1= new hen();
 25:            hen obj2= new hen();
 26:            obj1.aaa(1);        
 27:            obj1.aaa(20);
 28:            obj2.aaa(30);        
 29:            obj2.aaa(3);
 30:            System.out.println("obj1.Cno="+obj1.Cno);
 31:            System.out.println("obj1.SCno="+obj1.SCno);
 32:            //System.out.println("obj1.Rno="+obj1.Rno);
 33:            System.out.println("obj2.Cno="+obj2.Cno);
 34:            System.out.println("obj2.SCno="+obj2.SCno);
 35:            //System.out.println("obj2.Rno="+obj2.Rno);
 36:    } 

Rnoはaaa内のローカル関数なので、mainメソッドからは参照することができません。
もし、32&35行をコメントにしなかった場合は、エラーが怒ります。
[Mi:prgm/java/rep#5] j03040% javac rep5.java
rep5.java:32: シンボルを解決できません。
シンボル: 変数 Rno 
場所    : hen の クラス
                System.out.println("obj1.Rno="+obj1.Rno);
                                                   ^
rep5.java:35: シンボルを解決できません。
シンボル: 変数 Rno 
場所    : hen の クラス
                System.out.println("obj2.Rno="+obj2.Rno);
                                                   ^
エラー 2 個

でも、これは当たり前のことです、Rnoはローカル変数だから、
上記の通り、宣言されたメソッド以外から参照できません。
このような、参照できるかできないかを変数スコープ(有効範囲)と言います




もくじにもどる?




○色々なメソッド&アクセス

コンストラクタ
コンストラクタはオブジェクトを生成する時に必ず実行される。
初期化処理(一番最初に行われる処理)を書くところです。
コンストラクタはクラス名と同じ名前にしなければいけません。

コンストラクタの宣言方法
アクセスレベル コンストラクタ名(クラス名と同じ){ (引数)
public Sample (int x)

Staticイニシャライズ
Staticイニシャライズとは、
上記のコンストラクタよりも先に実行されるメソッドです。
一回実行したらプログラムが終了するまでは2度と実行されません。
一番最初に実行したいけど、一度実行したらもうやらなくてもいい処理を書く時に使います。

コンストラクタとstaticイニシャライズを使ったプログラム
[Mi:prgm/java/rep#5] j03040% java List meso.java
File name:meso.java
 1:/*
 2: * @day: 2003/12/10
 3: * @author j03040
 4: * @St-ID  035740F
 5: * 
 6: */
 7:class Cons{
 8:     static int n;         //static変数n
 9:     static{               //staticイニシャライザ
 10:            System.out.println("First!!!");    //最初にされる処理
 11:            n=0;                               //一度行ったらもうしない
 12:    }
 13:    Cons(){             //コンストラクタ
 14:            if (n==0){               //nが0だったここを行う
 15:            System.out.println("Second!!!"); 
 16:            n=1;          //nを1にする。
 17:            }
 18:            else if(n==1){      //nが1だったらここを行う
 19:                    System.out.println("Third!!!");
 20:            }
 21:    }
 22:}
 23:public class meso {
 24:    public static void main(String[] args) {
 25:             Cons obj1=new Cons();    //オブジェクト生成1
 26:             Cons obj2=new Cons();  //オブジェクト生成2
 27:    }
 28:}


実行結果

[Mi:prgm/java/rep#5] j03040% java meso
First!!!
Second!!!
Third!!!


25:でオブジェクトを作成しています。
オブジェクトを生成するとプログラムは最初に9:staticイニシャライザを実行します
次に13:のコンストラクタを実行します。
26:でまたオブジェクトを生成していますので、プログラムは7:にいきますが
イニシャライザは一回しか実行されないのですぐコンストラクタを実行します。



メソッドのオーバーロード
メソッドのオーバーロードとは、クラス内に同じ名前のメソッドを作る事を言います。
オーバーロードするときは、メソッドの引数の数、型等が互いに違うものにしなければいけません

オーバーロードのプログラム

[Mi:prgm/java/rep#5] j03040% java List Over.java
File name:Over.java
 1:/*
 2: * day: 2003/12/10
 3: * @author j03040
 4: * @St-ID  035740F
 5: */
 6:
 7:class enzan{
 8:     void en(){         //メソッドのオーバーロードno1
 9:             System.out.println("notthing!");
 10:    }
 11:    void en(int x){    //メソッドのオーバーロードno2
 12:            System.out.println(x+"*"+x+"="+x*x);
 13:    }
 14:    void en(int x,int y){   //メソッドのオーバーロードno3
 15:            System.out.println(x + "+"+ y +"="+ (x+y));
 16:    } 
 17:    void en(int x,int y,int z){     //メソッドのオーバーロードno4
 18:            System.out.println(x+"+"+y+"+"+z+"="+(x+y+z));
 19:    }
 20:}
 21:public class Over {
 22:    public static void main(String[] args) {
 23:            enzan obj=new enzan();
 24:            obj.en();              //no1を呼び出し
 25:            obj.en(10);      //no2を呼び出し
 26:            obj.en(1,2);      //no3を呼び出し
 27:            obj.en(10,20,30);      //no4を呼び出し
 28:    }
 29:}


実行結果

[j03040:prgm/java/rep#5] j03040% java Over
notthing!
10*10=100
1+2=3
10+20+30=60


と実行結果のように、同じ名前のメソッドでも引数の数をかえる事で
それぞれ違った処理をする事ができます。
つまりメソッドのオーバーロードをする事で、引数の数にそれぞれ違った処理をする
という処理を、if文やswith文を使わないでできるのできる。



アクセス制御
上記のように、オブジェクト指向プログラムでは(Java,C++,etc....)
クラスや、メソッド、変数などに、『アクセス』して使う事ができます。
しかし、中には自由にアクセスされては困るクラスなどもあります。
そのような場合に使うのがアクセス制御修飾子です。

アクセス制御修飾子とは。。。。。
その名前の通り、アクセスを制御する修飾子です。

アクセス制御修飾子
名前 説明
public 自由にアクセスできる
protected 定義されたクラス内のメソッド、同一パッケージ、
そのクラスから派生したサブクラスからアクセスできる
private 定義されたクラス内からだけアクセスできる

※ちなみにアクセス制御修飾子を省略した場合は
     同じパッケージからしかアクセスできなくなります。

アクセス制御のプログラム
[Mi:eclipse/workspace/report] j03040% java List acc.java
File name:acc.java
 1:/*
 2: * day: 2003/12/11
 3: * @author: j03040
 4: * St-ID:035740F
 5: */
 6:import java.io.*;
 7:class keisan{
 8:     static int tanka,total;         //static変数
 9:     private int himitu;             //private変数
 10:
 11:    private int Himitu(){           //privateメソッド
 12:            BufferedReader Reader=
 13:                    new BufferedReader(
 14:                             new InputStreamReader(System.in),1);
 15:
 16:            String date;
 17:            System.out.print("Input Date---->");
 18:            try{
 19:                    date=Reader.readLine();
 20:                    return Integer.parseInt(date);
 21:            }catch(Exception e){
 22:                    return 0;
 23:            }
 24:    }
 25:    keisan(){                        //コンストラクタ
 26:            total=0;
 27:            tanka=100;
 28:            himitu=0;
 29:    }
 30:    public void buy(){               //buyメソッド
 31:            keisan obj=new keisan(); //オブジェクト生成
 32:            himitu=obj.Himitu();     //himituを使う
 33:            total=tanka*himitu;      
 34:    }
 35:} 
 36:
 37:public class acc {
 38:    public static void main(String[] args) {
 39:            int a;
 40:            keisan obj=new keisan();       //オブジェクト生成
 41:            //a=obj.Himitu();              //Himituはprivateだからアクセス不可
 42:            obj.buy();                     //buy()を実行
 43:
 44:            System.out.println("Total="+obj.total);  //Totalを表示
 45:            System.out.println("Tanka="+obj.tanka);  //tankaを表示
 46:            //Syste.out.println("Himitu="+obj.himitu);//himituはアクセス不可
 47:    }
 48:}

実行結果
[Mi:eclipse/workspace/report] j03040% java acc
Input Date---->20
Total=2000
Tanka=100

41:と46:をコメントじゃなくしてコンパイルしてみると
[Mi:eclipse/workspace/report] j03040% javac acc.java
acc.java:41: Himitu() は keisan で private アクセスされます。
                a=obj.Himitu();
                     ^
acc.java:46: himitu は keisan で private アクセスされます。
                System.out.println("Himitu="+obj.himitu);
                                                ^
エラー 2 個


となります、Himituとhimituはprivateなので、mainメソッドからでは
クラスが違うのでアクセスできません。



もくじにもどる?

つぎにいく