オブジェクト指向へ向けて

<本章の目的>クラスの基礎を習得する。前半の終わりであり、後半の始まりであ〜る。

問題10-1 クラスを作り、それを用いたプログラムを作って下さい。

○答え

// Kamoku.java

public class Kamoku{
  String namae;
  int tensuu;
  public String mojiretsu(){
    return namae+"は"+tensuu+"点";
  }
  public String toString(){
    return namae+"は"+tensuu+"点";
  }
}


// KamokuTest.java

public class KamokuTest{
  public static void main(String[] args){
    Kamoku kamoku=new Kamoku();

    kamoku.namae="国語";
    kamoku.tensuu=63;

    System.out.println(kamoku.mojiretsu());
    System.out.println(kamoku);
  }
}


○実行結果

D:\atsushi\Java\p240>java KamokuTest
国語は63点
国語は63点
-- Press any key to exit (Input "c" to continue) --

○注意

Kamoku クラスと KamokuTest クラスは別々のソースファイルに書かなければなりません。
二つのソースファイルは同じフォルダに置いておくのが無難です。
また、実行したい場合は、両方ともコンパイルした後に、
KamokuTest の方をコマンドラインで指定しましょう。

○解説

// Kamoku.java

1. public class Kamoku{

public はアクセス制御キーワードの一つで、「誰でも使える」ことを表しています。

2. String namae;
3. int tensuu;

これらはフィールドです。
詳しくは問題10-2を参照して下さい。

4. public String mojiretsu(){

static が無いことに注目して下さい。
詳しくは後述します。

mojiretsu メソッドの処理内容
 return namae+"は"+tensuu+"点";
は、次のように書くことも出来ます。
 return toString();

7. public String toString(){

toString メソッドは特別なメソッドです。
文字列連結の演算子 + によってインスタンス(クラスの実体)を文字列に変換するとき、
そのインスタンスの toString() メソッドを自動的に呼び出します。
また、System.out.println() や System.out.print() にインスタンスを渡すと、
自動的にそのインスタンスの toString() を使って文字列に変換してから表示してくれます。

// KamokuTest.java

3. Kamoku kamoku=new Kamoku();

クラス宣言の基本的な書き方です。
クラスの名前の後の括弧 () が謎だと思うのですが、
これはデフォルトコンストラクタを呼び出しています。
C++言語の場合は括弧 () を省略した……と言うか、
明示的にコンストラクタを呼び出さなかった場合にデフォルトコンストラクタが呼び出されましたが、
さすがJava言語はチェックが厳しいですねー(汗)。
自分でデフォルトコンストラクタを呼び出さなければならないんですから。

クラスの実体のことをインスタンスと言います。
クラス型の変数のことではありません。
オブジェクトと言うこともあります。
抽象的なものであるクラスが、具体的なものとなることから、この名前が付けられました。
本問の場合も、科目情報を表すクラスが、国語の科目情報を表すインスタントとなりました。

9. System.out.println(kamoku);

インスタンスを渡すだけで、toString メソッドを自動的に呼び出します。

インスタンスメソッドとクラスメソッド

static キーワードが付いているメソッドはクラスメソッド、あるいは static メソッドと言います。
クラスメソッドは、インスタンスを作らなくても使えるメソッドです。
main メソッドやこれまで作ってきたメソッドはすべてクラスメソッドでした。

static キーワードが付いていないメソッドはインスタンスメソッド、あるいは非 static メソッドと言います。
クラスメソッドと違い、宣言されているクラス外部から
インスタンスメソッドを呼び出す為にはインスタンスを通す必要があります。
しかし、同じクラスのインスタンスメソッド同士ならばお互いを呼び出すことが可能です。


この辺はまだまだ情報不足で掴み切れません……。
もう暫くお待ちを(汗)。

○補足

フィールドにも、クラスフィールド、インスタンスフィールドというのがありますが、
こちらも、もう暫くお待ちを(汗)。

問題10-2 変数とフィールドの違いを述べて下さい。

// Field.java

public class Field{
  int a;
  public Field(int a,int b,int c){
    this.a=a;
    this.b=b;
    this.c=c;
  }
  int b;
  public String toString(){
    return "a="+a+" b="+b+" c="+c;
  }
  int c;
}


// FieldTest.java

public class FieldTest{
  public static void main(String[] args){
    Field field=new Field(1,2,3);
    System.out.println(field);
  }
}


○実行結果

D:\atsushi\Java\p254>java FieldTest
a=1 b=2 c=3
-- Press any key to exit (Input "c" to continue) --

○解説

Field クラスのインスタンス field はフィールドでしょうか?変数でしょうか?
答えは変数です。
フィールドは、そのクラスのどのメソッドからでも使えますが、
変数は、宣言されているメソッドの中でしか使えません。

a,b,c はフィールドです。

this は現在のインスタンスを表します。
this はフィールドと変数、引数が区別できないときに使います。
必ず使わなければいけないものではありません。
また、this はインスタンスメソッドの中でしか使うことが出来ません。

○補足

フィールドと変数は別物です。
したがって、フィールドと変数で同じ型、同じ名前の“もの”を作ることが出来ます。

問題10-3 クラス型配列を用いたプログラムを作って下さい。

○答え

// Kamoku.java

public class Kamoku{
  String namae;
  int tensuu;
  public Kamoku(String namae,int tensuu){
    this.namae=namae;
    this.tensuu=tensuu;
  }
  public String toString(){
    return namae+"は"+tensuu+"点";
  }
}


// KamokuHeikin.java

public class KamokuHeikin{
  public static void main(String[] args){
    Kamoku[] kamoku={
      new Kamoku("国語",63),
      new Kamoku("数学",90),
      new Kamoku("英語",75),
      new Kamoku("理科",45),
      new Kamoku("社会",81),
    };
    int sum=0;
    for(int i=0;i<kamoku.length;i++){
      System.out.println(kamoku[i]);
      sum+=kamoku[i].tensuu;
    }
    double heikin=(double)sum/kamoku.length;
    System.out.println("平均点は"+heikin+"点");
  }
}


○実行結果

D:\atsushi\Java\List10-3&4>java KamokuHeikin
国語は63点
数学は90点
英語は75点
理科は45点
社会は81点
平均点は70.8点
-- Press any key to exit (Input "c" to continue) --

○解説

// Kamoku.java

4. public Kamoku(String namae,int tensuu){

Kamoku メソッドはコンストラクタです。
コンストラクタにはいくつか決まりがあります。
・コンストラクタの名前はクラスの名前と同じ。
・コンストラクタの戻り値はない( void 型でもない)。


// KamokuHeikin.java

3. Kamoku[] kamoku={
4.  new Kamoku("国語",63),
5.  new Kamoku("数学",90),
6.  new Kamoku("英語",75),
7.  new Kamoku("理科",45),
8.  new Kamoku("社会",81),
9. };

Kamoku 型配列を作っています。
コンストラクタの使い方はC++言語と一緒ですね。
ちょっと分かり難いプログラムになっていますが、
分解すれば次と全く同じです。

Kamoku[] kamoku=new Kamoku[5];
kamoku[0]=new Kamoku("国語",63);
kamoku[1]=new Kamoku("数学",90);
kamoku[2]=new Kamoku("英語",75);
kamoku[3]=new Kamoku("理科",45);
kamoku[4]=new Kamoku("社会",81);

○補足

コンストラクタがある場合は、必ず使わなければなりません。
デフォルトコンストラクタは使えません。
これはC++言語でも同じでしたね。
コンストラクタは強く使うことを推奨されていますが、
宣言と同時に初期化しなければならないという欠点があるため、
敢えてコンストラクタは作らない、というのもアリです。

問題10-4 コンストラクタを多重定義して下さい。

○答え

長いので別窓でご用意致しました( ClickHere )。

○実行結果

D:\atsushi\Java\ListA10-2&3>java StudentTest
[結城浩,65,90,100] -> 255
[阿部和馬,82,73,64] -> 219
[伊藤光一,74,31,42] -> 147
[佐藤太郎,100,95,99] -> 294
-- Press any key to exit (Input "c" to continue) --

○解説

コンストラクタを多重定義しています。
それだけです(笑)。

tens=new int[]{x,y,z};

は、次と全く同じです。

tens=new int[3];
tens[0]=x;
tens[1]=y;
tens[2]=z;

問題10-5 クラスを返却値型とするメソッドを作って下さい。

○答え

class MyojiNamae{
  String myoji;
  String namae;
}

public class MethodTest4{
  public static MyojiNamae getYourName(){
    MyojiNamae obj=new MyojiNamae();
    obj.myoji="福沢";
    obj.namae="諭吉";
    return obj;
  }
  public static void main(String[] args){
    MyojiNamae mn=getYourName();
    System.out.println("名字は"+mn.myoji);
    System.out.println("名前は"+mn.namae);
  }
}


○実行結果

D:\atsushi\Java\ListA8-5>java MethodTest4
名字は福沢
名前は諭吉
-- Press any key to exit (Input "c" to continue) --

○解説

1. class MyojiNamae{

public が付いていないことに注目して下さい。
たぶん、このソースファイル内部でしか使えないのでしょう。

14. MyojiNamae mn=getYourName();

new していないことに注目して下さい。
mn に代入されたのは obj へのポインタです。
クラスは参照型ですからね。


戻る / ホーム