2003年度後期 IT教育基礎論演習B

第8回: オブジェクト指向プログラミング JAVA基礎

概要と目標

■ 概要

オブジェクト指向に基づくプログラミング言語の1つとしてJavaを例に取り、 プログラムの記述方法、コンパイル方法、実行方法を習得する。

■ 目標

目次

演習内容

■ はじめに〜Javaとは

近年注目されているプログラミング言語の1つとして、Java言語がある。 Java言語は、C++を参考にして開発されたコンパイル型の オブジェクト指向プログラミングパラダイムに基づくプログラミング言語 (オブジェクト指向プログラミング言語)である。

Java言語はコンパイル型言語であるが、通常のコンパイル型言語と異なり、 ソースプログラムをコンパイルすると 個々のコンピュータアーキテクチャやオペレーティングシステムに依存しない、 Javaアーキテクチャ用の実行可能コードが生成され、 この実行可能コードはJavaバーチャルマシンなどの上で実行される。

Java プログラムの実行形態
Javaプログラム(実行可能コード)
Javaバーチャルマシン
オペレーティングシステム
コンピュータシステム

これにより、UNIXシステムやWindows、MacOSなど、 異なるオペレーティングシステム上で 共通のプログラムを実行することが可能となっている。 ただし、Javaバーチャルマシンにより、実行可能コードを逐次解釈しながら プログラムの実行を行なうため、 実行速度が遅くなるというデメリットもある。

一般に、Java言語と、Javaバーチャルマシンなど、その実行環境とをあわせて、 Java と呼ぶことが多い。 なお、JavaScriptは、 Javaを利用してwebブラウザで利用できるスクリプト言語を実現したものであり、 Java言語とは異なる。

■ プログラムの記述と実行

Java言語により記述されたプログラムを実行するには、 C言語と同様に、先ず、記述されたソースプログラムをコンパイルする必要があるが、 このとき、生成された実行可能ファイルの実行方法には2種類の方法がある。

1つは、独立したJavaアプリケーションとして、 Javaバーチャルマシン上で直接実行する方法であり、 もう一方は、Webブラウザに組み込まれたJavaバーチャルマシンを利用し、 Webブラウザ上のJavaアプレットとして実行する方法であり、 両者は、それぞれプログラムの記述方法も異なる。 以下に、それぞれのプログラムの記述方法と実行方法を述べる。

□ Javaアプリケーション

Java言語により、独立したアプリケーションプログラムを記述するには、 先ず、エディタ等を利用してソースファイルを作成する。 例えば、簡単なJavaプログラムのソースファイルの内容は以下のようになる。

簡単なJavaアプリケーションプログラムの例(1): HelloWorld.java
ファイルの内容 意味
// HelloWorld.java コメント行
 
public class HelloWorld { HelloWorldクラスの定義開始
  public HelloWorld() { HelloWorldクラスのコンストラクタ定義開始
    System.out.println("Hello, World."); 文字列"Hello, World."の標準出力への出力
  } コンストラクタ定義終了
 
  public static void main(String[] args) {   クラスメソッド: main()の定義開始
    new HelloWorld(); HelloWorldクラスのインスタンス生成
  } main()メソッドの定義終了
} HelloWorldクラスの定義終了

このとき、アプリケーションプログラムとして実行される プログラムを記述したソースファイルには、 そのプログラムが実行された際に先ず始めに実行される main()メソッドを持ったクラスオブジェクトの定義が 記述されていなければならない。 またファイル名には、そのソースファイルにより定義されている パブリッククラスのクラス名に拡張子として".java"をつけた名前を使用する。 例えば、"HelloWorld"というクラスを定義している場合、 "HelloWorld.java"というファイル名とする。

記述されたJavaのソースファイルをコンパイルするには、 コマンドラインから以下のようにJavaコンパイラのコマンドである javacを実行する。

$ javac <source-file>

例えば、ソースファイルの名前が"HelloWorld.java"であれば、 コマンドラインに以下のように入力する。

$ javac HelloWorld.java

これにより、ソ−スファイルの中で定義されているクラス名に基づき、 実行可能ファイルとしてのJavaクラスファイルが生成される。 例えば、"HelloWorld"クラスを 定義しているソースファイルをコンパイルすると、 "HelloWorld.class"のファイル名で クラスファイルが生成される。

生成されたクラスファイルを実行するには、 javaバーチャルマシンとして機能するjavaコマンドを利用して、 以下のようにコマンドラインに入力する。

$ java <class-name>

ただし、javaコマンドの引数として指定するのはクラス名であり、 クラスファイル名であることに注意する。 すなわち、クラスファイルの拡張子である".java"はつけない。

例えば、クラスファイル名が"HelloWorld.class"であれば、 コマンドラインにjava HelloWorldと入力し、 その実行結果は以下のようになる。

$ java HelloWorld
Hello, World.

□ Javaアプレット

Javaアプレットのプログラムを作成する場合、 javacによるコンパイルによりクラスファイルを生成する方法は Javaアプリケーションを作成する方法と同様であるが、 定義するクラスはmain()メソッドを持っていなくともよく、 代わりに、アプレットの初期化のためのinit()メソッドや アプレット実行のためのstart()メソッド、 アプレットとしてのwebブラウザ上の表示領域への画面描画のための paint()メソッドなどを持つ、 Appletクラスを継承したものでなければならない。 例えば、アプレットのソースファイルの内容は以下のようになる。

簡単なJavaアプリケーションプログラムの例(1): HelloWorld.java
ファイルの内容 意味
// HelloWorldApplet.java コメント行
 
import java.awt.*; awtクラスライブラリの読み込み
import java.applet.*; appletクラスライブラリの読み込み
 
public class HelloWorldApplet extends Applet {   Appletクラスを継承して
HellowWorldAppletクラスの定義開始
  public void init() { init()メソッドの定義開始
    setBackground(Color.yellow); 背景色の定義
    setForeground(Color.blue); 前景色の定義
  } init()メソッドの定義終了
 
  public void start() { start()メソッドの定義開始
    repaint(); repaint()メソッドの呼び出し
  } start()メソッドの定義終了
 
  public void paint(Graphics g) { paint()メソッドの定義開始
    g.drawString("Hello, World.", 30, 30); 画面への文字列描画
  } paint()メソッドの定義開始
} HelloWorldクラスの定義終了

アプレットを定義したソースファイルをコンパイルして生成される クラスファイルを実行するには、アプレットビューア、 もしくはアプレット再生機能が組み込まれたwebブラウザを利用する。 webブラウザを利用してアプレットを実行する場合、 以下のようにアプレット実行方法を記述したHTMLファイルを用意する。

<applet code="<class-file-path>" <options> ... >
  <description for that the applet is not executed>
</applet>

例えば、HelloWorldAppletクラスを中央位置で 幅150ピクセル、高さ50ピクセルの大きさで実行する場合、 HTML中に以下のように記述するとよい。

<center>
  <applet code="HelloWorldApplet.class" width="150" height="50">
    アプレット実行例
  </applet>
</center>

このHTMLファイルをwebブラウザにより参照することにより、 アプレットが自動的に実行される。 この実行結果は、以下のようになる。

アプレットの実行例
アプレット実行例

■ オブジェクトの生成と実行

□ クラスとインスタンス

Java言語はオブジェクト指向プログラミング言語であるので、 プログラムの内容は基本的にオブジェクトの定義とその呼び出しからなる。 このとき、オブジェクトには、クラスオブジェクト(クラス)と インスタンスオブジェクト(インスタンス)がある。

オブジェクトとは、データとその処理手続きをカプセル化したものである。 一般に、データは変数に格納されて保持される。 この変数を属性とも呼ぶ。 また、処理手続きはメソッドと呼ばれ、 変数の操作方法や他のメソッドの呼び出しからなる。 新たにオブジェクトを定義するには、 そのオブジェクトの持つ属性とメソッドを定義する。 このように定義されたオブジェクトをクラスと呼ぶ。 すなわち、クラスとは、オブジェクトの定義そのものであり、 その定義内容を変更することができないオブジェクトである。

これに対しインスタンスは、クラスに基づき生成され、 自由に利用可能なオブジェクトである。 1つのクラスから複数のインスタンスを生成することが可能であり、 また、変更可能な属性の値を自由に変更することができる。

□ クラスの定義

新規クラスの定義

Java言語で、他のプログラムから利用可能なクラスを新たに定義する場合、 パブリッククラスと呼ばれるクラスを定義する。 パブリッククラスを定義するには、1つのパブリッククラスにつき、 以下の形式で1つのファイルを作成する。

<qualifier> class <class-name> {
  <variable-definitions>
      ...
  <method-definitions>
      ...
}

このとき、定義されたクラスからインスタンスを生成するためのメソッドとして、 コンストラクタと呼ばれる特別なメソッドを定義する必要がある。 コンストラクタは、パブリッククラス名に"("と")"で囲んで引数を指定した形となる。

例えば、新しく多角形を示すパブリッククラスとして インスタンスとしての多角形の名前と頂点の数を属性を持つ Polygonクラスを定義する場合、 先ず、以下のようなファイルを作成する。

新規クラスの定義: Polygon.java
// Polygon.java

public class Polygon {
    public String name;
    public int points;

    public Polygon(String n, int p) {
	name = n;
	points = p;
    }
}

これを以下のようにコンパイルすることにより Polygonクラスが生成され、 他のプログラムから利用できるようになる。 ただし、このPolygonクラスはmain()メソッドを持たないため、 1つのアプリケーションプログラムとしては実行することはできない。

$ javac Polygon.java
クラスの継承

もし、あるクラスの定義の一部を変更した新たなクラスを定義したい場合には、 もとのクラスを継承(インヘリタンス)したサブクラスを新たに定義する。 サブクラスを定義するには、以下の形式で記述する。

<qualifier> class <class-name> extends <parent-class-name> {
    <variable-definitions>
        ...
    <method-definitions>
        ...
}

このとき、コンストラクタを定義するには、 継承もとの上位クラスのコンストラクタを呼び出した後に、 必要な処理を行う手続きを記述する必要がある。 上位クラスのコンストラクタはsuper()により参照することができる。

例えば、多角形を示すPolygonクラスを継承し、 その面積を求めるメソッドを持つ平行四角形を示すParallelogram クラスを定義する場合、 以下のようなプログラムを記述することができる。

クラスの継承: Parallelogram.java
// Parallelogram.java

public class Parallelogram extends Polygon {
    public double width, height;

    public Parallelogram(String n, double w, double h) {
	super( n, 4 );
	width = w;
	height = h;
    }

    public double Area() {
	return width * height;
    }
}

これを以下のようにコンパイルすることにより、 Parallelogramクラスが生成される。

$ javac Parallelogram.java

□ インスタンスの生成

定義されたクラスからインスタンスを生成するには、以下のように、 先ず、生成されたインスタンスを代入するための変数を用意し、 コンストラクタを実行した結果を代入する。 これにより、生成されたインスタンスが変数に代入され、利用可能となる。 このとき、変数の型には、そのクラス名を記述する。

<type> <variable>;
  ...
<variable> = new <constructor>;

変数の宣言と同時にインスタンスを生成する場合、 以下のようにまとめて記述することもできる。

<type> <variable> = new <constructor>;

例えば、Parallelogramクラスのインスタンスを生成する場合、 以下のように記述することができる。

Parallelogram p = new Parallelogram( "P1", 2, 3 );

生成されたインスタンスの変数を参照したり、メソッドを利用する場合、 以下のように、インスタンスが代入されている変数の後ろに"."で区切って 変数名やメソッドを指定する。

<variable>.<variable-of-instance>                      // 変数を参照する場合
<variable>.<method-of-instance> (<argments>, ...)      // メソッドを実行する場合

例えば、 Parallelogramクラスのインスタンスを生成して利用する例として、 以下のようなプログラムを記述することができる。

インスタンスの生成と利用: ParallelogramUse.java
// ParallelogramUse.java

public class ParallelogramUse {

    public static void main(String[] args) {
	Parallelogram p = new Parallelogram( "P1", 2, 3 );

	System.out.print( p.name + ": ");
	System.out.print( "width: " + p.width + ", " );
	System.out.print( "height: " + p.height + ", " );
	System.out.println( "size: " + p.Area() );
    }
}

このプログラムをコンパイルし、実行すると以下のような結果を得る。

$ javac ParallelogramUse.java
$ java ParallelogramUse
P1: width: 2.0, height: 3.0, size: 6.0

1つのクラスから、異なる属性値を持つ複数のインスタンスを生成し、 利用することもできる。 例えば、配列を利用して複数のParallelogramクラスの インスタンスを利用するプログラムを以下のように記述することができる。

複数のインスタンスの生成と利用: ParallelogramContainer.java
// ParallelogramContainer.java

public class ParallelogramContainer {
    static Parallelogram elements[];
    static int amount;

    ParallelogramContainer(int size) {
	elements = new Parallelogram[size];
	amount = 0;
    }

    public static int addElement(String name, int width, int height) {
	elements[amount] = new Parallelogram(name, width, height);
	amount++;

	return amount;
    }

    public static int showElements() {
	int i;

	for( i = 0; i < amount; i++ ) {
	    System.out.print( elements[i].name + ": ");
	    System.out.print( "width: " + elements[i].width + ", " );
	    System.out.print( "height: " + elements[i].height + ", " );
	    System.out.println( "size: " + elements[i].Area() );
	}

	return amount;
    }

    public static void main(String[] args) {
	ParallelogramContainer container = new ParallelogramContainer(3);

	container.addElement( "P1", 2, 3 );
	container.addElement( "P2", 4, 5 );
	container.addElement( "P2", 5, 2 );

	container.showElements();
    }
}

このプログラムをコンパイルし、実行すると以下のような結果を得る。

$ javac ParallelogramContainer.java
$ java ParallelogramContainer
P1: width: 2.0, height: 3.0, size: 6.0
P2: width: 4.0, height: 5.0, size: 20.0
P2: width: 5.0, height: 2.0, size: 10.0

■ クラスライブラリの利用

Javaでは、あらかじめ、様々なクラスをクラスライブラリとして提供している。 このようなクラスライブラリを利用することにより、 複雑なプログラムを効率よく簡単に記述することができる。 Javaで提供されるクラスライブラリを利用するためには、 以下のように、import文により、使用したいクラスライブラリが 格納されているパッケージと、使用したいクラスを指定する。

import <package>.<class-name>.<sub-class-name>...

あるパッケージに含まれるクラス全体や、 あるクラスのサブクラス全体を利用したい場合、 以下のように、クラス名を明示的に指定するかわりに"*"を指定する。

import <package>.<class-name>.*

例えば、アプレットクラスを利用したい場合、 アプレットクラスは"java"というパッケージに含まれるので、 以下のように記述する。

import java.applet.*

これにより、appletクラスを使用したプログラムを記述することができる。

■ 演習課題

□ 演習課題1

レポート課題

■ レポート課題1

Polygonクラスを継承し、 属性として底辺の長さと高さ、 また、メソッドとして底辺の長さと高さから面積を求める手続き、 および名前、底辺の長さ、および長さを指定してインスタンスを生成する コンストラクタとしての手続きを持つ 三角形を示すtriangleクラスを定義せよ。

次に、triangleクラスから底辺の長さが3、 高さが4のインスタンスを生成し、 その面積を求めるプログラムを作成せよ。

■ レポート課題2

属性としてID(文字列)、氏名(文字列)、性別(整数、0: 男性、1: 女性) 年齢(整数)、 また、メソッドとしてID、氏名、性別、年齢を指定してインスタンスを生成する コンストラクタを持つpersonクラスを定義せよ。

次に、personクラスのインスタンスを要素とする配列により、 学生一覧を登録し(プログラムの中に記述して良い)、 その一覧を表示するプログラムを作成せよ。

■ レポート課題3

以下のJAVAアプレットプログラムを入力し、webブラウザ上で実行せよ。 レポートには、プログラムのソース、アプレットを実行するためのHTMLファイル、 および実行結果を示せ。

HiHelloアプレット: HiHello.java
// HiHello.java

import java.applet.Applet;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class HiHello extends Applet implements ActionListener {
    Button button;
    String string[]
	= { "Hello!", "Hi Hello!", "How are you?", "Fine, Thank you." };
    int i = 0;

    // 初期化
    public void init() {
		button = new Button("Fine, Thank you.");
		this.add(button);
		button.addActionListener(this);
    }

    // 実行開始
    public void start() {
	repaint();
    }

    // 描画
    public void paint(Graphics g) {
	button.setLabel(string[i]);
    }

    // ボタンが押された際の処理
    public void actionPerformed(ActionEvent e) {
	i = (i + 1) % 4;
	this.repaint();
    }
}

参考書籍、Web

  1. (株)オフィスエム 著: 「最新Javaハンドブック」, (株)秀和システム, ISBN4-7980-0215-1, ¥2,800-
  2. SUGAI, Manabu: 「浅煎り珈琲 Javaアプリケーション入門」, http://msugai.fc2web.com/java/index.html

Last modified: Mon Nov 24 20:52:58 JST 2003