6 章: クラス I

クラス

Java でプログラムを作成するときに, 必要なデータや処理をひとつもまとまりに記述する. このまとまりがクラスであり, このクラスを組み合わせてプログラムを組み立てていく.

データや処理などをどのようにまとめるか, [まとめたもの] (= オブジェクト) をどのように組み合わせるかなどを思考すること.

Java 言語は [オブジェクト指向型言語] と言われている.

クラスの構成

クラスは次の要素で構成されている:

1. メンバ変数
2. メソッド

Sample0601.java

1
2
3
4
5
6
7
public class Sample0601{
    static String str = "Hello Java World"; // メンバ変数

    public static void main(String[] args){ // メソッド
	System.out.println(str);
    }
}

上記のプログラムの実行結果:

[wtopia 6]$ java Sample0601
Hello Java World

クラスの書式

クラスの書式は次の通りである:

[アクセス修飾子] [修飾子リスト] class クラス名{
}

メンバ変数

メンバ変数とはクラス内で保持するデータを定義するもの.

メンバ変数の書式は次の通りである:

[アクセス修飾子] [修飾子リスト] 型 変数名;

メンバ変数へのアクセス

メンバ変数へアクセスするには次のように [.] (ドット演算子) を使用する:

[クラス.メンバ変数]

注意:

[private] では上記のようにクラス外からアクセスできない

メソッド:

メソッドは処理を記述することができ クラスに機能を与えるもの.

メソッドの書式

メソッドの書式は次の通りである:

[アクセス修飾子] [修飾子リスト] 戻り値の型 メソッド名(引数リスト){
}

注意:

1. 戻り値が無いときは [void] を記述する
2. 引数リストは省略可能

引数リストの形式は次のようになる:

型 変数1, 型 変数2, ...

メソッドの使用

メソッドの使用方法は次のように [.] [ドット演算子] を使用する:

クラス.メソッド(引数リスト);

注意:

[private] では上記のようにクラス外からアクセスできない.

オーバーロード

Java では [メソッド] をメソッド名で一意とするのではなく, [メソッド名 + 引数リスト] (この組み合せ [シグニチャ] と言う) で一意とする仕様になっている. つまり [引数の型] や [引数の数] が異なれば同じ名前のメソッドを複数作ることができるわけ.

同じメソッド名で [引数リスト] のみが異なるメソッドを用意することをメソッドの [オーバーロード] と言う.

Sample0602.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class Sample0602{
    public static void main(String[] args){
	Sample0602.load("a");

	load("a");
	load("a", "b");
	load(1);
    }

    public static void load(String s){ // クラスメソッド
	System.out.println("[ load(String s) ] が呼ばれた.");
    }

    public static void load(String s1, String s2){ // クラスメソッド
	System.out.println("[ load(String s1, String s2) ] が呼ばれた.");
    }

    public static void load(int i){ // クラスメソッド
	System.out.println("[ load(int i) ] が呼ばれた.");
    }
}

上記のプログラムの実行結果:

[wtopia 6]$ java Sample0602
[ load(String s) ] が呼ばれた.
[ load(String s) ] が呼ばれた.
[ load(String s1, String s2) ] が呼ばれた.
[ load(int i) ] が呼ばれた.

インスタンス

クラスには上記例のような使用方法もあるが, オブジェクト指向本来の威力を発揮する主要な方法が別にある.

それはクラスから [インスタンス] を生成して利用する方法. [インスタンス] はそれ自身を型として取り扱うことができるので, メンバ変数の値が異なる [インスタンス] を複数作成することも可能.

インスタンスの生成

インスタンスを生成するには [new] 演算子を使用する.

インスタンスの生成の書式:

インスタンスの型 インスタンス変数 = new クラス名(引数リスト);

[インスタンスの型] とは:

1. インスタンス自身の [クラス]
2. 親クラス (スーパークラス)
3. インタフェース

メンバ変数およびメソッドへのアクセス

インスタンスの [メンバ変数] と [メソッド] はそれぞれ, [インスタンス変数], [インスタンスメソッド] と呼ばれる.

アクセス方法は, クラスのときと同様に [.] (ドット演算子) を使用する.

メンバ変数の呼び出し:

インスタンス.メンバ変数;

メソッドの呼び出し:

インスタンス.メソッド名(引数リスト);

インスタンスの使用例

生徒クラス (Sample0603Student) からインスタンスを2つ生成して, それぞれに名前を設定する. 各インスタンスを独立して取り扱っているところがポイント.

Sample0603.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Sample0603{
    public static void main(String[] args){
	// インスタンスの生成
	Sample0603Student student1 = new Sample0603Student();
	Sample0603Student student2 = new Sample0603Student();

	// それぞれのインスタンスに名前を設定
	student1.setName("WTOPIA");
	student2.setName("YANGGUANG");

	// それぞれのインスタンスから名前を取得
	System.out.println(student1.getName());
	System.out.println(student2.getName());
    }
}

class Sample0603Student{
    public String name = "";

    public void setName(String name){
	this.name = name;
    }

    public String getName(){
	return name;
    }
}

上記のプログラムの実行結果:

[wtopia 6]$ java Sample0603
WTOPIA
YANGGUANG

コンストラクタ

Java には [コンストラクタ] という特別なメソッドが用意されている. コンストラクタはインスタンスを生成時, つまりクラスを [new] したときに呼び出される.

インスタンス生成時に呼び出されることから, よくインスタンスの初期化処理に利用される.

ちなみに C++ にはインスタンスが破棄される時に呼び出される [デストラクタ] と呼ばれるメソッドがあるが, Java ではインスタンスの破棄は JVM が管理しておりプログラムで制御できないため:

[デストラクタ] は用意されない.

コンストラクタの条件は次の通り:

1. 戻り値を指定しない (void も記述しない)
2. コンストラクタ名はクラス名と同じであること

よって, コンストラクタの書式は次のようになる:

class クラス名{
  [アクセス修飾子] クラス名(引数リスト){
    処理1
    処理2
  }
}

また, コンストラクタも通常のメソッドのように [オーバーロード] することができる. コンストラクタの場合, 呼び出されるのはインスタンス生成時であるから [new] するときに指定された引数の形式により, コンストラクタの呼び分けが行われる.

Sample0604.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Sample0604{
    public static void main(String[] args){
	// コンストラクタで名前を設定するように変更
	Sample0604Student student1=new Sample0604Student("FeiZhao");
	Sample0604Student student2=new Sample0604Student("YangGuang");

	System.out.println(student1.getName());
	System.out.println(student2.getName());
    }
}

class Sample0604Student{
    public String name = "";

    // コンストラクタの追加
    public Sample0604Student(String name){
	this.name = name;
    }

    public String getName(){
	return name;
    }
}

上記のプログラムの実行結果:

[wtopia 6]$ java Sample0604
FeiZhao
YangGuang

new せずに使用できるインスタンス

インスタンスを生成するには [new] 演算子を使用すると説明したが, 主に次のような場合, [new] をせずにインスタンスを使用することができる.

  1. String 形を使用するとき. ([new] して生成することも可能):
String str = “do not use new”;
  1. 配列の初期化するとき (初期化以外は [new] が必要):
int array[] = {1, 2, 3};
  1. 基本データ型のラッパークラスに対するオートボクシング (Autoboxing) 機能による自動変換のとき:
Integer i = 0;

クラスとインスタンスの関係

パソコンには作られた時点で CPU やメモリなどの性能 (スペック) が備わっている. パソコンは OS により挙動が変化する. この場合 [クラス] と [インスタンス] の関係は次のようなイメージで表現できる.

_images/java-class101.gif

つまり, メンバ変数ごとに挙動を変えるものとして取り扱いたい場合, 上記の例では OS により [Win パソコン], [Mac パソコン], [Linux パソコン] といったもの (オブジェクト) がインスタンスであり, インスタンスの処理になる. 反対にメンバ変数などにより挙動を変化させる必要がない (インスタンスを生成する必要がないとも言える) の場合にはクラスで処理を行う.

プログラムソース上での違い

注意:

[static] が付いてるどうか.

クラスとインスタンスそれぞれのメンバ変数とメソッドの違い

_images/static1.gif

Sample0605.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Sample0605{
    public static void main(String[] args){
	Sample0605PC pcW = new Sample0605PC("Win"); // [Win パソコン] インスタンス
	Sample0605PC pcM = new Sample0605PC("Mac"); // [Mac パソコン] インスタンス
	Sample0605PC pcL = new Sample0605PC("Linux"); // [Linux パソコン] インスタンス
	System.out.println( pcW.execOS() );
	System.out.println( pcM.execOS() );
	System.out.println( pcL.execOS() );

	System.out.println( Sample0605PC.isSPEC() ); // [パソコン] クラスの処理
    }
}

class Sample0605PC{
    private String os = ""; // インスタンス変数
    private static String spec = "CPU: 2.4GHZ, MEM: 1GB, HD:500GB"; // クラス変数

    public Sample0605PC(String os){ // コンストラクタ
	this.os = os;
    }

    public String execOS(){ // インスタンスメソッド
	return "["+os+"] パソコンを機能した";
    }

    public static String isSPEC(){ // クラスメソッド
	return spec;
    }
}

上記のプログラムの実行結果:

[wtopia 6]$ java Sample0605
[Win] パソコンを機能した
[Mac] パソコンを機能した
[Linux] パソコンを機能した
CPU: 2.4GHZ, MEM: 1GB, HD:500GB