新しい変数の型としてのクラス

オブジェクト指向以前のやり方

オブジェクト指向とはなにか、オブジェクト指向以前のやり方と比較することでつかんでいきたい。

配列の練習で Goukei.java をつくりました。たくさんの数値を配列に読み込んでおき、合計を求めるものでした。これがある科目の試験の結果で、生徒の名前も一緒に処理したいという時のことを考えてみます。これをクラシックなやり方ではこうなります。(名前は実在の人物ではありません)

ファイル名 Goukei2.java

public class Goukei2 { 
    public static void main( String[] args ) {
       String[] namae = {"岩井 亜紀","河合 和子","木原 園子",
                        "布川 麻子","福永 秋絵","三上 美奈",
                        "矢島 千晶","吉沢 裕子","渡辺 智子" };
       int[] ten     = {78,45,65,35,92,63,57,89,84};
       double goukei = 0;
       for ( int i=0; i < ten.length ; i++ ){
           System.out.print( namae[i] );
           System.out.print( " " );
           System.out.println( ten[i] );
           goukei = goukei + ten[i];
       }
       System.out.println( goukei );
       System.out.println( goukei/ten.length );
    }
}

これできちんと処理されますが、プログラムの中では名前と点数が別々の配列に入れられていて、番号で結びつけられています。プログラム言語の都合に合わせてデータの入れ方を工夫しています。

しかし、元のデータは次のような固まりになっているのです。

"岩井 亜紀",78
"河合 和子",45
"木原 園子",65
"布川 麻子",35
............

プログラムが複雑になり、プログラミングが共同作業になるにつれ、現実のデータを元の形で扱いたいと考えるようになりました。現実のデータの都合に合わせてプログラム言語の仕様を工夫したことになります。これはプログラム言語がオブジェクト指向になった理由のひとつです。

オブジェクト指向のやり方

新しい変数の型を作る

まず、新しい変数の型(実際の名前はクラス)をつくります。

ファイル名 Seito1Kamoku.java

名前の由来は生徒1科目です。

public class Seito1Kamoku { 
    /* フィールド */
    String namae;
    int ten;
    /* コンストラクタ */
    public Seito1Kamoku( String s, int n ){
       namae = s;
       ten   = n;
    }
}

今回のクラスは今までのと異なり、mainの部分がありません。ですからこのまま実行することはできません。新しい変数の型を定義しただけです。

新しい型の名前は Seito1Kamoku で、名前と点数をセットで代入することができます。フィールドと描かれている部分でそれを指定しています。

この新しい型の変数は使う時に宣言だけでなく、メモリ上に場所を用意するために new という操作を必要とします。コンストラクタはこの時にしなければならないことを書いておきます。

新しい型の変数を使う

次にこれを使うプログラムを書きます。まずは、2人分の名前と点数を代入し、表示してみます。

ファイル名 Goukei3.java

public class Goukei3 { 
    public static void main( String[] args ) {
       Seito1Kamoku seito1 = new Seito1Kamoku("岩井 亜紀",78);
       Seito1Kamoku seito2 = new Seito1Kamoku("河合 和子",45);

       System.out.print( seito1.namae );
       System.out.print( " " );
       System.out.println( seito1.ten );

       System.out.print( seito2.namae );
       System.out.print( " " );
       System.out.println( seito2.ten );
    }
}

実行結果は次の通り。

U:\user\java> java Goukei3
岩井 亜紀 78
河合 和子 45

クラスとインスタンス

普通のint型の変数と比較します。

普通の変数 int tensuu1 = 78;
新型の変数 Seito1Kamoku seito1 = new Seito1Kamoku("岩井 亜紀",78);

型の名前 変数の名前 = という部分は共通です。ただし、新型の変数は値を代入する以外にもいろいろな機能を持たせることができるので「変数の型」といわずに「クラス」。「変数」といわずに「インスタンス」(最近はオブジェクト)といいます。

カタカナで書くと専門用語のようで難しそうですが、英語では日常的に使う言葉です。次のような意味です。

言葉 クラス インスタンス オブジェクト
意味 分類・種類・なかま・学級 例・実例 もの

正式には、宣言部分は

int tensuu1;      「 tensuu1 はint型の変数である。」
Seito1Kamoku seito1;  「 seito1 は Seito1Kamokuクラスのインスタンスである。」あるいは、
            「 seito1 というオブジェクトは Seito1Kamokuクラスである。」

というのですが、その意味は、

Seito1Kamoku seito1;  「 seito1 は Seito1Kamokuの種類の1例である。」あるいは、
            「 seito1 というものは Seito1Kamokuのなかまである。」

となって、従来よりも考えやすい概念になっています。

コンストラクタ

変数 tensuu1 では = 78 と単に初期値を代入しています。seito1 では、= new Seito1Kamoku("岩井 亜紀",78); のようにしています。オブジェクトには複数のデータが組み合わされていますから単純に代入できません。ここでjavaはSeito1Kamokuに必要な量のメモリを確保し、コンストラクタに従って初期値を代入します。

Seito1Kamokuには、namae と ten の2つのフィールドがある。
コンストラクタは public Seito1Kamoku( String s, int n )
new Seito1Kamoku("岩井 亜紀",78)の部分で、
s が"岩井 亜紀",  n が 78 となってコンストラクタが呼ばれる
コンストラクタ中の
       namae = s;
       ten   = n;
で、namae と ten の2つのフィールドに、s, n の内容が代入され、オブジェクトができる。

フィールドの操作

オブジェクト seito1 には、namae と ten の2つのフィールドがある。(Seito1Kamokuのクラスのオブジェクトはすべてこうなっている)この2つのフィールドは次のようにすると普通の変数のように取り扱うことができる。

seito1.namae
seito1.ten

オブジェクトを配列に格納

オブジェクトを配列に格納し9人の処理をすることにする。

ファイル名 Goukei4.java

public class Goukei4 { 
    public static void main( String[] args ) {
       Seito1Kamoku[] test1 = {
               new Seito1Kamoku("岩井 亜紀",78),
               new Seito1Kamoku("河合 和子",45),
               new Seito1Kamoku("木原 園子",65),
               new Seito1Kamoku("布川 麻子",35),
               new Seito1Kamoku("福永 秋絵",92),
               new Seito1Kamoku("三上 美奈",63),
               new Seito1Kamoku("矢島 千晶",57),
               new Seito1Kamoku("吉沢 裕子",89),
               new Seito1Kamoku("渡辺 智子",84)
       };
       double goukei = 0;
       for ( int i=0; i < test1.length ; i++ ){
           System.out.print( test1[i].namae );
           System.out.print( " " );
           System.out.println( test1[i].ten );
           goukei = goukei + test1[i].ten;
       }
       System.out.println( goukei );
       System.out.println( goukei/test1.length );
    }
}

結果は

U:\user\java> java Goukei4
岩井 亜紀 78
河合 和子 45
木原 園子 65
布川 麻子 35
福永 秋絵 92
三上 美奈 63
矢島 千晶 57
吉沢 裕子 89
渡辺 智子 84
608.0
67.55555555555556

解説

上記のやり方は、

int[] kazu = {12, 23, 34, 45, 56};

に相当する。大きさだけ決めておいて後で代入する方法もあった。

int[] kazu = new int[5];

この方法でオブジェクトの配列を作る場合は次のようにする。

       Seito1Kamoku[] test1 = new Seito1Kamoku[9];

       test1[0] =  new Seito1Kamoku("岩井 亜紀",78);
       test1[1] =  new Seito1Kamoku("河合 和子",45);
       test1[2] =  new Seito1Kamoku("木原 園子",65);
       test1[3] =  new Seito1Kamoku("布川 麻子",35);
       test1[4] =  new Seito1Kamoku("福永 秋絵",92);
       test1[5] =  new Seito1Kamoku("三上 美奈",63);
       test1[6] =  new Seito1Kamoku("矢島 千晶",57);
       test1[7] =  new Seito1Kamoku("吉沢 裕子",89);
       test1[8] =  new Seito1Kamoku("渡辺 智子",84);
もくじ

聖愛高等学校
http://www.seiai.ed.jp/
Last Modified