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
メンバ変数へアクセスするには次のように [.] (ドット演算子) を使用する:
[クラス.メンバ変数]
注意:
[private] では上記のようにクラス外からアクセスできない
メソッド:
メソッドは処理を記述することができ クラスに機能を与えるもの.
メソッドの書式は次の通りである:
[アクセス修飾子] [修飾子リスト] 戻り値の型 メソッド名(引数リスト){
}
注意:
1. 戻り値が無いときは [void] を記述する
2. 引数リストは省略可能
引数リストの形式は次のようになる:
型 変数1, 型 変数2, ...
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] をせずにインスタンスを使用することができる.
String str = “do not use new”;
int array[] = {1, 2, 3};
Integer i = 0;
パソコンには作られた時点で CPU やメモリなどの性能 (スペック) が備わっている. パソコンは OS により挙動が変化する. この場合 [クラス] と [インスタンス] の関係は次のようなイメージで表現できる.
つまり, メンバ変数ごとに挙動を変えるものとして取り扱いたい場合, 上記の例では OS により [Win パソコン], [Mac パソコン], [Linux パソコン] といったもの (オブジェクト) がインスタンスであり, インスタンスの処理になる. 反対にメンバ変数などにより挙動を変化させる必要がない (インスタンスを生成する必要がないとも言える) の場合にはクラスで処理を行う.
注意:
[static] が付いてるどうか.
クラスとインスタンスそれぞれのメンバ変数とメソッドの違い
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