オブジェクトとは

いろいろな属性を持つデータを一度に扱って1つの変数に出し入れするために, Pascalではレコード型,C言語では構造体(structure)というものが用意されて いる.

たとえば,2次元座標上の点を double 型2つで表すとする時,C言語では,

struct Point2D {
  double x,y;
};
と宣言しておくと,(struct Point2D)型の変数 p に対して,p.xでX座標が p.yでY座標が参照できる.

このような目的のために,Java言語ではオブジェクト型を用いる.オブジェ クト型のことはクラス(class)と呼ぶ.ファイルの中だけで有効なオブジェク ト型の宣言は,

  // Point2Dという名前のクラスを作る。クラス名は大文字で始めるのが一般的
class Point2D {
    // Point2Dクラスは double型の x, y というデータフィールド
    // (インスタンス変数)を持つ
  public double x,y;
}
のようにおこなう(ファイルの外,同じパッケージ内(後述)で有効なオブジェ クト型を宣言する時は,classの前に public をつける.ただし,その場合は 同じソースファイル内では宣言できず,「クラス名.java」という名前の別の ファイルにする必要がある).
同じものを「オブジェクト型」と呼んだり「クラス」と呼んだり,プログラ ミング言語の世界では用語の統一が取られていないことが多い.プログラミン グ言語一般を専門とする人は,型の一つとして「オブジェクト型」と呼ぶこと が多いのに対して,オブジェクト指向言語を専門とする人は「オブジェクト型」 では概念が広すぎるという理由で「クラス」を使うことが多い.

オブジェクト指向言語を専門とする人の中でも,なじみのあるプログラミン グ言語が何かによって,用語が変わることがあるので注意が必要になる.

これで,Point2Dという名前が型名として使うことができる. Point2D型の変数の宣言は,

  Point2D p1;
のようにおこなう.

オブジェクト型の変数を宣言だけして,代入しない状態ではその変数には nullという何も入っていないことを示す印が入っている(説明を忘れたが,配 列型の変数も同様.).オブジェクト型では,まずは,「new クラス名()」と やって作る必要がある.これを「あるクラスのインスタンスを作る」と言う.

クラスとインスタンスの関係は,設計図と製品の関係に似ている.同じ設計 図から製品をいくつも作ることができる.これが「new クラス名()」にあたる. 普通の完成品である製品と違って,インスタンスは部品のようなもので,基本 データ型を入れる箱や,他の部品をはめ込むための穴を持っているとイメージ できる.

このPoint2Dクラスにオブジェクト(インスタンス)を作った模式図は以下のようになる.

「new クラス名()」で作ったあとは,さきほどの例では x, yのような,その インスタンス中の変数(インスタンス変数)は,C言語同様「.インスタンス変数 名」をつけるとそのインスタンスのインスタンス変数にアクセスすることがで きる.インスタンス変数のことをデータフィールドとも呼ぶ.

例を見てみよう.

  // Point2Dという名前のクラスの宣言
class Point2D {
    // インスタンス変数 x, y の宣言
  public double x,y;
}

public class ObjectTest1 {
  public static void main(String[] args){
    Point2D p1,p2,p3;
      // Point2Dクラスのオブジェクトを作って 変数 p1に入れる。
    p1=new Point2D();
      // p1のインスタンス変数、x, y のそれぞれに値を入れる。
    p1.x=0.0; 
    p1.y=0.0;
    p2=new Point2D();
    p2.x=1.0; 
    p2.y=1.0;
    p3=new Point2D();
    p3.x=0.0; 
    p3.y=1.0;
      // ローカル変数 dx, dy, rの宣言
    double dx,dy,r;
      // p1, p2のx座標の差を dxに、y座標の差を dyに入れる
    dx=(p1.x-p2.x);dy=(p1.y-p2.y);
      // dx, dyの2乗和の平方根(square root)を計算し rに入れる。
    r=Math.sqrt(dx*dx+dy*dy);
      // 表示
    System.out.println("distance between p1 and p2 "+r);
    dx=(p2.x-p3.x);dy=(p2.y-p3.y);
    r=Math.sqrt(dx*dx+dy*dy);
    System.out.println("distance between p2 and p3 "+r);
    dx=(p3.x-p1.x);dy=(p3.y-p1.y);
    r=Math.sqrt(dx*dx+dy*dy);
    System.out.println("distance between p3 and p1 "+r);
  }
}
「数値データを扱う場合はなぜ new がいらないのか?」というのは,当然疑 問に持っていいことである.たとえば,定数"1"を作るのに"new int(1)"とし たっていいじゃないかと思うかもしれない.こう書かない理由としては,
  1. 基本データ型がオブジェクト型でないことを表すため.
  2. いちいち new をつけると書くのが面倒だし,つけなくても"1"だけで, intだと分かる.
などの理由が考えられる.実際のところ,オブジェクト型の一つである Stringの定数も new をつけないし,数値データがオブジェクト型である Smalltalk-80でもnewはつけなかったので,後者の方が正しいだろう.

次へ進む
ktanaka@XXX.ecc.u-tokyo.ac.jp