クラスとインスタンス
“Hello World”という文字列は、文字列を表すStringクラスのインスタンスになります。
インスタンスは具体的な「特定のもの」を表しています。インスタンスはクラスに属しています。すべてのインスタンスは、インスタンスが属しているクラスに共通の性質を持ちます。
classは「種類」や「部類」という意味の英語で、instanceは「実例」や「具体的な事物」という意味の英語です。
つまり、classは「抽象的」で、instanceは「具体的」と考えることができます。
例えば、車classを作ったとして、設定できることは「抽象的」なことになります。
・車は、タイヤがあります。
・車は、エンジンがついています。
・車は、ボディーの色があります。
・車は、ボディーの形があります。
・車は、走ります。
上記のような、どの車にも当てはまるような属性を決めておくのが、classになります。
車classの中で、1つだけ異なる属性が含まれています。
それは、「車は、走ります」です。他の属性は日本語で言えば「名詞」にあたるものですが、「車は、走ります」というのは「動詞」にあたるものになります。
classの中で「名詞」にあたるものを、Javaでは「フィールド」といいます。フィールドは情報を保存する場所を表しています。
また、「動詞」にあたるものを、Javaでは「メソッド」といいます。メソッドは情報を処理する方法を表します。
実際に、車classの「抽象的」な属性を「具体的」にすることを「インスタンス化」するといいます。
車classをインスタンス化してみましょう。
・車のタイヤは、ミシュランです。
・車のエンジンは、EJ20 です。
・車のボディー色は、ブラックです。
・車のボディー形状は、ステーションワゴンです。
・ブラックのステーションワゴンは、EJ20の動力でミシュランを転がして走ります。
クラスにはどんな種類があるか
Javaには、多くのクラスがありますが、最初から用意されているクラスと、自分で作成するクラスがあります。
通常、自分で作成するクラスの場合は、クラスの宣言が必要です。
最初から用意されているクラスとしては、文字列を表すStringクラスがあります。
ファイルの読み書きには、FileReaderクラスやFileWriterクラスがあります。
Java言語でプログラムを開発するときには、クラスライブラリのマニュアルを読む必要があります。
クラスを宣言する
Javaでは自分でクラスを作ることができます。逆に、Javaのプログラムは全てクラスからできており、クラスを宣言することなくプログラムを作ることはできません。
class MyClass{
//フィールドの宣言
//メソッドの宣言
}
「class」はJavaの予約語で、クラス宣言の始まりを示します。
「MyClass」はクラスの名前で、自分で決めることができます。クラスの名前は大文字で始めるのが慣習になっており、クラスの名前は名詞を使うことが多いです。また、「MyClass」の「C」が大文字になっているのは、クラス名の途中でスペースが使えないため、単語の区切りが分かりやすいように大文字になっています。
フィールドとメソッド
クラスはフィールドとメソッドを持っています。
フィールドは変数のようなもので、メソッドは関数のようなものです。
フィールドとメソッドがクラスの性質を決めることになります。
フィールド
フィールドは情報を保存する場所を表します。
たとえば、「長方形」のクラスをつくるとして、「幅」と「高さ」は長方形の「情報」になります。
長方形クラスとして、Rectangleクラスを宣言してみます。
class Rectangle{
int width;
int height;
}
この長方形クラスでは、数値としての、width(幅)とheight(高さ)が存在しているという、長方形の特徴を示しています。注意してほしいのは、具体的な数値の決まった長方形はまだできていないと言うことです。クラスの宣言は「抽象的」なのです。これを「具体的」にするにはインスタンスを作る必要があります。
メソッド
メソッドは情報を処理する方法を表します。先ほどの、Rectangleクラスに下記の2つのメソッドを追加します。
・幅と高さを設定する(setSize)
・面積を計算する(getArea)
class Rectangle{
int width;
int height;
void setSize(int w, int h){
this.width = w;
this.height = h;
}
int getArea(){
return width * height;
}
}
setSizeメソッド
void setSize(int w, int h)
voidはJavaの予約語で、処理の結果として戻り値を返さないという意味になります。voidは「空」や「無効」という意味になります。
setSizeはメソッドの名前です。メソッドの名前は小文字で始めるのが慣習となっています。
(int w, int h)は、メソッドの「仮引数」です。仮引数はこのメソッドをインスタンス化したときの入力にあたるもので、型名(int)と仮引数(w)をコンマで区切って、もう一つの仮引数int hをつなげています。つまり、このメソッドには仮引数が2つあることになります。
this.width = w;
ここで、widthというフィールドに仮引数のwを代入しています。先頭についているthisはこのクラスのフィールドであることを示しています。
this.height = h;
heightというフィールドに仮引数のhを代入しています。
getAreaメソッド
int getArea()
最初のintは、このメソッドの処理結果としての「戻り値の型」を表しています。計算した長方形の面積をint型で返すということになります。
また、()カッコの中に何も書いていませんので、このメソッドには仮引数はありません。面積を計算するのに必要な情報はすでにフィールドに保存されており、その情報を使って計算するからです。
return width * height;
returnはJavaの予約後で、直後に戻り値となる式を書きます。
width*heightは、幅と高さを掛け算して長方形の面積を求めています。widthもheightもフィールドになりますので、先ほどのsetSizeメソッドで何らかのint型の数値が設定されているはずです。int型の数値を掛け算するので、計算結果もint型となり、setSizeメソッドの型とgetAreaメソッドの型は一致することになります。
インスタンスの作り方
インスタンスを作るには、Javaの予約語であるnew演算子を使います。
作ったインスタンスを、Rectangle型として宣言した変数rに代入します。
そうすると、以降のプログラムで変数rを使ってインスタンスを利用することができます。
Rectangle r = new Rectangle()
フィールドへのアクセス
インスタンスとして、変数rを用意しましたので、クラスのフィールドに数値を代入してみます。
Rectangle r = new Rectangle();
r.width = 123;
r.height = 45;
メソッドの呼び出し
先ほど、クラスのフィールドに数値を代入しましたが、すでにクラスには数値を設定するメソッドである、setSizeメソッドを用意していました。このメソッドを使うと、数値の代入がもっと簡単になります。
Rectangle r = new Rectangle();
r.setSize(123,45);
メソッドの呼び出しは、インスタンスとして用意した変数rに続けてドットを打ち、メソッド名を書く形です。この時、カッコ内が引数となりますが、メソッドの第1引数を123として、第2引数を45とするようにカンマで区切って書いています。この「123」や「45」といった具体的な数値が、先ほどの「仮引数」に対する「実引数」となります。メソッドの宣言時には決まっていなかった仮引数が、このメソッドの呼び出し時の実引数によって決まったことになります。
このメソッドの呼び出しで、クラスのフィールドは次の値を持つことになります。
int width = 123;
int height = 45;
コンストラクタ
先ほどから作っている長方形クラスなのですが、幅や高さは長方形には必須の情報になります。
毎回、長方形をインスタンス化するときに、setSizeメソッドを呼び出すのも面倒です。
このように、当たり前に設定しなければならないものを、インスタンスを作成すると同時に設定できる方法として、コンストラクタがあります。つまり、インスタンスを初期値で「初期化」すると言い換えても良いかもしれません。
コンストラクタの宣言
class Rectangle{
int width;
int height;
Rectangle(int w, int h){ //コンストラクタここから
width = w;
height = h;
} //コンストラクタここまで
void setSize(int w, int h){
this.width = w;
this.height = h;
}
int getArea(){
return width * height;
}
}
コンストラクタはメソッドの宣言と似ていますが、違いは以下の2点です。
(1)コンストラクタには戻り値の型がない(voidでもない)
(2)コンストラクタの名前はクラス名と同じ(Rectangle)
他にも、コンストラクタの中で、他のメソッド(setSize)を呼び出して利用しても大丈夫です。
class Rectangle{
int width;
int height;
Rectangle(int w, int h){ //コンストラクタここから
setSize(w,h);
} //コンストラクタここまで
void setSize(int w, int h){
this.width = w;
this.height = h;
}
int getArea(){
return width * height;
}
}
コンストラクタの呼び出し
幅と高さを指定したコンストラクタを呼び出し、Rectangle型の変数rにインスタンスを代入するには、次のように書きます。
Rectangle r = new Rectangle(123,45);
引数なしコンストラクタ
最初から長方形の幅と高さを決めておきたいときは、引数なしのコンストラクタを使います。例えば、幅が10、高さが20であると引数を指定しない時のインスタンスの初期値を設定するのが、引数なしのコンストラクタになります。
class Rectangle{
int width;
int height;
Rectangle(){ //引数なしコンストラクタここから
setSize(10,20);
} //引数なしコンストラクタここまで
Rectangle(int w, int h){ //コンストラクタここから
setSize(w,h);
} //コンストラクタここまで
void setSize(int w, int h){
this.width = w;
this.height = h;
}
int getArea(){
return width * height;
}
}
mainメソッド
ここまで、Rectangleクラスを作ってきましたが、実際にプログラムを動かすには、mainメソッドが必要になります。
mainメソッドは下記のように「{」から「}」の間に記述します。
public static void main(String[]args){
・・・
}
class Rectangle{
int width;
int height;
Rectangle(){ //引数なしコンストラクタここから
setSize(10,20);
} //引数なしコンストラクタここまで
Rectangle(int w, int h){ //コンストラクタここから
setSize(w,h);
} //コンストラクタここまで
void setSize(int w, int h){
this.width = w;
this.height = h;
}
int getArea(){
return width * height;
}
public static void main(String[]args){
Rectangle r1 = new Rectangle();
System.out.println("r1の幅は、" + "r1.width" + "です。");
System.out.println("r1の高さは、" + "r1.height" + "です。");
System.out.println("r1の面積は、" + "r1.getArea()" + "です。");
Rectangle r2 = new Rectangle(123,45);
System.out.println("r2の幅は、" + "r2.width" + "です。");
System.out.println("r2の高さは、" + "r2.height" + "です。");
System.out.println("r2の面積は、" + "r2.getArea()" + "です。");
}
}