第6章 オブジェクト指向

はじめに

前章まではJavaの文法の大部分を説明しました。演算子の意味、for文やwhile文による反復処理、if文による条件分岐、そしてメソッドの作り方まで行いました。プログラムを記述するために必要な知識であれば、これで十分です。

しかしながら、現代社会では必要とされる多くのプログラムはどんどん複雑になり規模も大きくなってきます。例えばインターネット、Web、データベースなどここ20年ほどの間に大きく変わってしまい、社会が要求するレベルもどんどん高くなっているのです。

このような中で従来のように、反復と条件分岐だけで論理を積み上げるやり方では、開発が難しいことは誰もが感じていました。そんな中で、注目を集めたのがオブジェクト指向技術でした。

ここでは、オブジェクト指向の考え方や作り方、使い方を中心に学習します。オブジェクト指向を理解し、オブジェクトの作り方・使い方をできるようになりましょう。

目次

  • オブジェクト指向
  • クラスとオブジェクト
  • クラスの作り方
  • オブジェクトの作り方
  • オブジェクトの使い方
  • コンストラクタ
  • コンストラクタのオーバーロード
  • メソッドのオーバーロード
  • 章のまとめ

目標

オブジェクト指向を理解し、オブジェクトの作り方・使い方をできるようになること

オブジェクト指向

オブジェクト指向とは、現実世界に存在する「もの」を中心にモデル化する考え方のことです。オブジェクトとは「もの」という意味を持ち、現実世界に存在するさまざまな事柄を指します。オブジェクトには、実際に目に見えるものや抽象的な事柄も含まれます。またモデル化とは、複雑なものや事柄をわかりやすい形に表現する方法です。例えば、ある場所をモデル化したものは地図になります。

オブジェクト指向に基づいてプログラムを作成することをオブジェクト指向プログラミングといいます。また、オブジェクト指向プログラミングを行うための言語をオブジェクト指向言語といいます。Java言語は、オブジェクト指向言語の一つです。

オブジェクト指向プログラミングのメリット

オブジェクト指向に基づいてプログラミングをすると以下2つのメリットがあります。

  • プログラムの部品化規格化ができる
  • 汎用システムを作成できる

プログラムの部品化、規格化ができる

例えば、現実世界の自動車を想像してください。
自動車を構成する一つ一つのオブジェクトは部品でできています。
自動車を作るときには、窓やタイヤやボディーやライトなどの部品を作成し、一旦テストします。そして、それぞれのテストされた部品を組み合わせて自動車が完成します。一旦テストされた部品を組み合わせて自動車という製品を作るので、故障のない製品を大量生産することが可能です。

ソフトウェアの世界でも同じように、システムを作成するときには機能ごとに部品を作成し、作成した部品を一旦テストをおこないます。そして、それぞれのテストされた部品を組み合わせてシステムを作成していきます。一旦テストされた部品を組み合わせてシステムを作成することで、故障のないシステムを作成できることができます。

汎用システムを作成できる

システムを作成するときには機能単位オブジェクトを作成します。機能単位にオブジェクトを作成しておくことで、他のシステムを新たに作成する際、既存のシステムと類似している機能に関しては汎用することができます。新たに一から作成しなくても、既存システムで作成してあるオブジェクトを活用することで、効率的に新たなシステムも作成することが可能です。

クラスとオブジェクト

プログラムの中でオブジェクトを作成するためには設計図が必要です。Javaではオブジェクトの設計図のことをクラスといいます。設計図(クラス)があれば、オブジェクトを必要に応じていくつでも作ることができます。

クラスには、オブジェクト必要な属性(変数)と操作(メソッド)を定義します。

  • 属性(変数)
    そのクラスをもとに生成されたオブジェクトの特性状態を表すデータにあたるもの

  • 操作(メソッド)
    そのクラスをもとに生成されたオブジェクトの動作振る舞いを表す処理にあたるもの

クラスを作成することで、複数のオブジェクトを生成することができます。

クラスの作り方

以下はクラスの定義です。

クラスは変数メソッドで構成されています。クラスを作成する際に定義する変数メソッドをメンバ(またはフィールドと呼びます。変数の場合はメンバ変数、メソッドの場合はメンバメソッドと呼びます。

それでは実際にクラスを作成(定義)してみましょう。
今回は、例として車を扱います。

まず、車のデータに次のようなものがあったとします。

名前 ナンバー ガゾリンの量 ボディー色
RX7 1234 20 blue
レスサス 3456 30 white
Rワゴン 7890 50 red
タスカン 6543 40 orange

これらをクラスとして定義する際に必要となるデータは、個々の値ではなく、「名前」、「ナンバー」、「ガソリン」、「ボディー色」などの項目です。項目名は属性に分類されます。

属性を定義する際は変数(メンバ変数)を宣言します。

また、車には以下のような動き(振る舞い)があります。

  • 進む
  • 止まる

これらをクラスとして定義する際は操作に分類されます。操作メソッド(メンバメソッド)という形でクラスへ定義します。

例題

それでは、Carクラスの中に以下の条件の属性(変数(メンバ変数))操作(メソッド(メンバメソッド))を定義してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {
System.out.println( "-----------------" );
System.out.println( "名前:" + carName );
System.out.println( "ナンバー:" + number );
System.out.println( "ガソリン:" + gass );
System.out.println( "ボディー色:" + bodyCorlor );
System.out.println( "-----------------" );
}

}

コンパイル例:

> javac chapter6¥Car.java

※今まで作成(定義)してきたクラスは、main()メソッドを定義したクラスで、実行する為の特別なクラスです。
今回作成したCarクラスは、main()メソッドを定義しないクラスです。
その為、実行することはできません。(ここでは、コンパイルのみ実施して下さい。)

オブジェクトの作り方

クラスを元にオブジェクトを生成することインスタンス化といいます。
インスタンス化するためにはnew演算子を使います。
new演算子は、配列を作成するときも使いましたが、新しいオブジェクトを作る演算子です。

先ほど定義した車クラス(Carクラス)から、車オブジェクト(Carオブジェクト)を生成してみましょう。

以下、CarExecクラスを作成して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{


/**
* mainメソッド
*/
public static void main(String[] args) {

//Car型の変数carを宣言
Car car;

//Carオブジェクトを生成し、Carクラス型の変数carへ代入
car = new Car();

}
}

インスタンス化したオブジェクトを扱うためには、参照型変数が必要です。
参照型変数は、オブジェクトアドレス(メモリの場所)代入することができる変数です。
オブジェクトアドレス代入すると、オブジェクトへアクセスすることができます。
オブジェクトアクセスすることを参照といい、参照できる範囲が、代入したときの変数の型で決まってきます。

参照型変数は、今まで扱ってきた変数と同様で、利用するためには宣言代入が必要です。

Carクラス型の変数carを宣言する場合

//Car型の変数carを宣言
Car car;

上記で宣言したCar型の変数carには、Car型のオブジェクトの参照を代入することができます。

オブジェクトはnew演算子を使用することで、作成できます。

以下は、new演算子を使ってCar型のオブジェクトを生成し、それを変数carへ代入しています。

car = new Car();

通常は、以下のように宣言代入を同時に行ないます。

Car car = new Car();

※ 変数の宣言代入を同時に行うことを初期化といいます。

Car型の変数carへCarオブジェクトのアドレスを代入すると、car変数はCarクラスで定義しているメンバの範囲で、Carオブジェクトへ参照することができます。

以下のように、CarExecクラスを修正してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{


/**
* mainメソッド
*/
public static void main(String[] args) {

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = car = new Car();

}
}

new演算子を実行すると、クラス定義を解読して、ヒープと呼ばれる記憶領域に新しいオブジェクトが作成されます。実際に変数へ代入されているのは、ヒープ領域に作成されたオブジェクトのアドレスです。オブジェクトを利用するときは、そのアドレスを参照することで、オブジェクトへアクセスすることができます。

オブジェクトの使い方

オブジェクトは、new演算子で生成した直後は、既定値(nullや0など)が入っています。

  • オブジェクト生成時の初期値
データ型 既定値
boolean false
char ¥u0000
byte 0
short 0
int 0
long 0
float 0.0
double 0.0
String null
配列型 null

オブジェエクトをnew演算子で作成したに、具体的なデータ(値)代入するためにはメンバー演算子(.)を使用します。

[構文]

オブジェクトのアドレスが代入してある変数名.メンバ変数名 = 値;

先ほど作成したCarExecクラスに、以下を追記してください。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = car = new Car();

//----ここから(追記)----

//メンバ変数にデータ(値)を代入
car.carName = "RX7"; //名前「"RX7"」をCarオブジェクトのメンバ変数carNameへ代入。
car.number = 1234; //ナンバー「1234」をCarオブジェクトのメンバ変数numberへ代入。
car.gass = 20; //ガソリン「20」リットルをCarオブジェクトのメンバ変数gassへ代入。
car.bodyCorlor = "blue"; //ボディー色「"blue"」をCarオブジェクトのメンバ変数bodyCorlorへ代入。

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定。
car.stop(); //Carオブジェクトのstop()メソッドを実行。

//----ここまで(追記)----
}
}

入力できたら、コンパイルおよび実行し、実行結果を確認して下さい。

コンパイル例:

> javac chapter6¥CarExec.java

※Carクラスをコンパイルしてない場合には、Carクラスを先にコンパイルしてから、
CarExecクラスをコンパイルして下さい。

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

コンストラクタ

new演算子で作成した直後のオブジェクトのフィールドには、意味のある具体的な値ではなく、null0などが入っています。そのためこれまでの例題では、後から特定の値をもう一度代入していました。

コンストラクタを作成すると、オブジェクト作成時に特定の値をメンバ変数代入することができます。

コンストラクタとは

コンストラクタとはオブジェクトを作成する際に同時に初期化を行う仕組みのことです。

Carクラスへコンストラクタの定義を追加し、CarExecでコンストラクタを利用してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

//----ここから(追記)----

/**
* コンストラクタ
*/
public Car(String a, int b , int c , String d ){

carName = a;
number = b;
gass = c;
bodyCorlor = d;

}

//----ここまで(追記)----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {
System.out.println( "-----------------" );
System.out.println( "名前:" + carName );
System.out.println( "ナンバー:" + number );
System.out.println( "ガソリン:" + gass );
System.out.println( "ボディー色:" + bodyCorlor );
System.out.println( "-----------------" );
}

}

CarExecクラスの以下の箇所を修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//Car型の変数carを宣言
Car car;

//----ここから(修正)----

//Carオブジェクトを生成し、Carクラス型の変数carへ代入
car = new Car("RX7", 1234, 20, "blue");

//----ここまで(修正)----

//----ここから(削除)----
//メンバ変数にデータ(値)を代入
//car.carName = "RX7"; //名前「"RX7"」をCarオブジェクトのメンバ変数carNameへ代入。
//car.number = 1234; //ナンバー「1234」をCarオブジェクトのメンバ変数numberへ代入。
//car.gass = 20; //ガソリン「20」リットルをCarオブジェクトのメンバ変数gassへ代入。
//car.bodyCorlor = "blue"; //ボディー色「"blue"」をCarオブジェクトのメンバ変数bodyCorlorへ代入。
//----ここまで(削除)----

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。

}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

コンストラクタの定義

コンストラクタは、次のような形式で定義します。

コンストラクタには、以下のルールがあります。

  • コンストラクタ名は、クラス名と同じにしなければならない

  • 戻り値を書かない(voidも書かない)(書いてしまうとメソッドになる。)

  • public省略可能
    publicは「利用に制限がない」という意味のキーワードです。同じパッケージの中すべてのクラスを作成する場合には省略できます。

コンストラクタの利用

コンストラクタを利用するときは、new演算子とセットで使います。

引数の値を設定するとき、コンストラクタの定義通り設定します。並び順個数同じでなければなりません。

thisキーワード

コンストラクタの引数は、推奨する書き方が決められています。それは、引数の名前対応するメンバ変数と同じにすることです。これにより引数とメンバ変数の対応が明確になるからです。ただし、単に同じ名前にすると、区別がつかなくなります。

Carクラスの以下の箇所を修正し、実行結果を確認してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

//----ここから(修正)----

/**
* コンストラクタ
*/
public Car(String carName, int number , int gass , String bodyCorlor ){

carName = carName;
number = number;
gass = gass;
bodyCorlor = bodyCorlor;

}

//----ここまで(修正)----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {
System.out.println( "-----------------" );
System.out.println( "名前:" + carName );
System.out.println( "ナンバー:" + number );
System.out.println( "ガソリン:" + gass );
System.out.println( "ボディー色:" + bodyCorlor );
System.out.println( "-----------------" );
}

}
項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = new Car("RX7", 1234, 20, "blue");

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。
}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:null
ナンバー:0
ガソリン:0
ボディー色:null
-----------------
右へ進む
止まる

上記の場合、Carクラス内で定義されているコンストラクタで、引数リスト
と、メンバ変数の名前が一緒で区別がつかない為、処理できず、既定値のnullや0が代入されます。

このような場合にはthisキーワードを使います。

コンストラクタ内でのthisキーワード利用

Carクラスのコンストラクタ内の処理を、以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタ
*/
public Car(String carName, int number , int gass , String bodyCorlor ){

//----ここから(修正)----
this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
//----ここまで(修正)----

}

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {
System.out.println( "-----------------" );
System.out.println( "名前:" + carName );
System.out.println( "ナンバー:" + number );
System.out.println( "ガソリン:" + gass );
System.out.println( "ボディー色:" + bodyCorlor );
System.out.println( "-----------------" );
}

}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

thisとはこのオブジェクトという意味があります。
this.carName、this.number、this.gass、this.bodyCorlorはCarオブジェクトのメンバ変数を指します。

thisキーワードを使うことで、メンバ変数引数代入することが、明確になります。

メソッド内でのthisキーワード利用

thisキーワードは、メソッド内で利用することも可能です。

以下、Carクラスのdisp()メソッド内で利用されているメンバ変数へ、thisを指定して
実行結果を確認してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタ
*/
public Car(String carName, int number , int gass , String bodyCorlor ){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;

}

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

//----ここから(修正)----
System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );
//----ここまで(修正)----

}

}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

コンストラクタと同様に、メソッド内もthisキーワードを使うことで、
メンバ変数明確に指定することができます。

コンストラクタの引数

コンストラクタメンバ変数初期値を設定できれば良いので、引数の並び順個数メンバ変数と同じでなくても構いません。

先ほど作成したCarクラスのコンストラクタの引数と処理内容を以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/
int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

//-----ここから(修正)-----

/**
* コンストラクタ
*/
public Car(int number , String bodyCorlor, String carName ){

this.number = number;
this.bodyCorlor = bodyCorlor;
this.gass = 20;
this.carName = carName;

}

//-----ここまで(修正)-----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

CarExecクラスのCarオブジェクト生成時の引数を、以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//-----ここから(修正)-----

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = new Car(1234, "blue", "RX7");

//-----ここまで(修正)-----

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。
}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

メンバ変数をリテラルで初期化

毎回メンバ変数へ初期化する値が同じであれば、メンバ変数へ直接リテラル設定することもできます。

Carクラスのメンバ変数gassへ直接リテラルの20を設定し、コンストラクタ内の処理を修正して下さい

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

//-----ここから(修正)-----

int gass = 10;

//-----ここまで(修正)-----

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタ
*/
public Car(int number , String bodyCorlor, String carName ){

this.number = number;
this.bodyCorlor = bodyCorlor;

//-----ここから(削除)-----

//this.gass = 20;

//-----ここまで(削除)-----

this.carName = carName;

}

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

今回はCarExecクラスの変更は無いです。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = new Car(1234, "blue", "RX7");

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。
}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
-----------------
名前:RX7
ナンバー:1234
ガソリン:10
ボディー色:blue
-----------------
右へ進む
止まる

コンストラクタ内に処理を記述する

コンストラクタ内にはreturn文以外であれば、任意の処理も書くことが可能です。

Carクラスのコンストラクタを、以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

//-----ここから(修正(元に戻す))-----

int gass;

//-----ここまで(修正(元に戻す))-----

/**
* 車のボディー色を保持
*/
String bodyCorlor;

//-----ここから(修正)-----

/**
* コンストラクタ
*/
public Car(String carName, int number, int gass, String bodyCorlor){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
System.out.println("Carクラスのコンストラクタ実行")
}

//-----ここまで(修正)-----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

CarExecクラスを以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//Car型の変数carを宣言
Car car;

//----ここから(修正)----

//Carオブジェクトを生成し、Car型の変数carへ初期化する
Car car = new Car("RX7", 1234, 20, "blue");

//----ここまで(修正)----

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。

}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
Carクラスのコンストラクタ実行
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる

コンストラクタのオーバーロード

複数のコンストラクタの定義

コンストラクタは、メンバ変数に初期値を設定するのが役割なので、いろいろな設定方法を選択できれば便利です。そこで、他のコンストラクタと区別できれば、コンストラクタを複数定義しても良いことになっています。

他のコンストラクタと区別するというのは、次のことを意味しています。

  • 引数の数が違う
  • 引数の並び順が違う
  • 引数の型が違う

複数コンストラクタを定義することをコンストラクタのオーバーロードといいます。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

//-----ここから(修正/追加)-----

/**
* コンストラクタA
*/
public Car(String carName, int number, int gass, String bodyCorlor){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
System.out.println("CarクラスのコンストラクタAを実行");
}

/**
* コンストラクタB
*/
public Car(String carName, int number, int gass ){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = "white";
System.out.println("CarクラスのコンストラクタBを実行");
}

/**
* コンストラクタC
*/
public Car(String carName, int number ){

this.carName = carName;
this.number = number;
this.gass = 50;
this.bodyCorlor = "red";
System.out.println("CarクラスのコンストラクタCを実行");
}

/**
* コンストラクタD
*/
public Car(String carName ){

this.carName = carName;
this.number = 6543;
this.gass = 50;
this.bodyCorlor = "orange";
System.out.println("CarクラスのコンストラクタDを実行");
}
//-----ここまで(修正/追加)-----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

CarExecクラスを、以下のように修正して下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

//----ここから(修正)----

//Carオブジェクトを生成(コンストラクタA利用)し、Car型の変数carへ初期化する
Car carA = new Car("RX7", 1234, 20, "blue");

//Carオブジェクトを生成(コンストラクタB利用)し、Car型の変数carへ初期化する
Car carB = new Car("レスサス", 3456, 30 );

//Carオブジェクトを生成(コンストラクタC利用)し、Car型の変数carへ初期化する
Car carC = new Car("Rワゴン", 7890 );

//Carオブジェクトを生成(コンストラクタD利用)し、Car型の変数carへ初期化する
Car carD = new Car("タスカン");


//メンバメソッドを実行(CarオブジェクトA)
carA.disp(); //CarオブジェクトAのdisp()メソッドを実行。
carA.goRun("右"); //CarオブジェクトAのgass()メソッドを実行。引数に"右"を指定
carA.stop(); //CarオブジェクトAのstop()メソッドを実行。

//メンバメソッドを実行(CarオブジェクトB)
carB.disp(); //CarオブジェクトBのdisp()メソッドを実行。
carB.goRun("左"); //CarオブジェクトBのgass()メソッドを実行。引数に"左"を指定
carB.stop(); //CarオブジェクトBのstop()メソッドを実行。

//メンバメソッドを実行(CarオブジェクトC)
carC.disp(); //CarオブジェクトCのdisp()メソッドを実行。
carC.goRun("前"); //CarオブジェクトCのgass()メソッドを実行。引数に"前"を指定
carC.stop(); //CarオブジェクトCのstop()メソッドを実行。

//メンバメソッドを実行(CarオブジェクトB)
carD.disp(); //CarオブジェクトDのdisp()メソッドを実行。
carD.goRun("後ろ"); //CarオブジェクトDのgass()メソッドを実行。引数に"後ろ"を指定
carD.stop(); //CarオブジェクトDのstop()メソッドを実行。

//----ここまで(修正)----
}
}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
CarクラスのコンストラクタAを実行
CarクラスのコンストラクタBを実行
CarクラスのコンストラクタCを実行
CarクラスのコンストラクタDを実行
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる
-----------------
名前:レスサス
ナンバー:3456
ガソリン:30
ボディー色:white
-----------------
左へ進む
止まる
-----------------
名前:Rワゴン
ナンバー:7890
ガソリン:50
ボディー色:red
-----------------
前へ進む
止まる
-----------------
名前:タスカン
ナンバー:6543
ガソリン:50
ボディー色:orange
-----------------
後ろへ進む
止まる

デフォルトコンストラクタ

プログラマがコンストラクタを1つも作成しない場合Javaコンパイラが自動作成するコンストラクタデフォルトコンストラクタといいます。デフォルトコンストラクタは引数がなく、何も処理しないコンストラクタです。

以下、CarDefaultクラスとCarDefaultExecクラスを新たに作成し、実行結果を確認しましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarDefault
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class CarDefault{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;


/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}
項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 CarDefaultExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class CarDefaultExec{


/**
* mainメソッド
*/
public static void main(String[] args) {

//Carオブジェクトを生成し、Carクラス型の変数carを初期化
Car car = new Car();

//メンバメソッドを実行
car.disp(); //Carオブジェクトのdisp()メソッドを実行。
car.goRun("右"); //Carオブジェクトのgass()メソッドを実行。引数に"右"を指定
car.stop(); //Carオブジェクトのstop()メソッドを実行。

}
}

コンパイル例:

> javac chapter6¥Login.java
> javac chapter6¥LoginExec.java

実行例:

> java chapter6.LoginExec
-----------------
名前:null
ナンバー:0
ガソリン:0
ボディー色:null
-----------------
右へ進む
止まる

上記、CarDefaultクラスにコンストラクタが定義されていないので、コンパイル時に、コンパイラが自動的にデフォルトコンストラクタ(以下のコンストラクタ)を作成します。

//CarDefaultクラスのデフォルトコンストラクタ
public CarDefault(){}

尚、デフォルトコンストラクタのアクセス修飾子(public or デフォルトアクセス)は、クラスと同じになります。
※アクセス修飾子については後述の章で説明します。

1つでも明示的にプログラマがコンストラクタを作成すると、デフォルトコンストラクタ自動作成されなくなりますので注意して下さい。

コンストラクタの簡略化

プログラミングは、同じ処理は何度も書かないこと、もしくは一箇所にまとめることが一般的です。

先ほど作成したCarクラスを見て下さい。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタA
*/
public Car(String carName, int number, int gass, String bodyCorlor){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
System.out.println("CarクラスのコンストラクタAを実行");
}

/**
* コンストラクタB
*/
public Car(String carName, int number, int gass ){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = "white";
System.out.println("CarクラスのコンストラクタBを実行");
}

/**
* コンストラクタC
*/
public Car(String carName, int number ){

this.carName = carName;
this.number = number;
this.gass = 50;
this.bodyCorlor = "red";
System.out.println("CarクラスのコンストラクタCを実行");
}

/**
* コンストラクタD
*/
public Car(String carName ){

this.carName = carName;
this.number = 6543;
this.gass = 50;
this.bodyCorlor = "orange";
System.out.println("CarクラスのコンストラクタDを実行");
}

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

CarクラスのコンストラクタAからDまでの処理で、同じ処理がいくつもあります。
(メンバ変数へ代入する処理が複数あります。)

上記のようなコンストラクタの定義の場合には、thisキーワードを使って処理をまとめることが可能です。

CarクラスのコンストラクタBからDまでの処理を、以下へ修正してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタA
*/
public Car(String carName, int number, int gass, String bodyCorlor){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
System.out.println("CarクラスのコンストラクタAを実行");
}

//-----ここから(修正)-----

/**
* コンストラクタB
*/
public Car(String carName, int number, int gass ){

this(carName, number, gass, "white"); //コンストラクタAを実行
System.out.println("CarクラスのコンストラクタBを実行");
}

/**
* コンストラクタC
*/
public Car(String carName, int number ){

this(carName, number, 50, "red"); //コンストラクタAを実行
System.out.println("CarクラスのコンストラクタCを実行");
}

/**
* コンストラクタD
*/
public Car(String carName ){

this(carName, 6543, 50, "orange"); //コンストラクタAを実行
System.out.println("CarクラスのコンストラクタDを実行");
}

//-----ここまで(修正)-----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

コンパイル例:

> javac chapter6¥Car.java
> javac chapter6¥CarExec.java

実行例:

> java chapter6.CarExec
CarクラスのコンストラクタAを実行
CarクラスのコンストラクタAを実行
CarクラスのコンストラクタBを実行
CarクラスのコンストラクタAを実行
CarクラスのコンストラクタCを実行
CarクラスのコンストラクタAを実行
CarクラスのコンストラクタDを実行
-----------------
名前:RX7
ナンバー:1234
ガソリン:20
ボディー色:blue
-----------------
右へ進む
止まる
-----------------
名前:レスサス
ナンバー:3456
ガソリン:30
ボディー色:white
-----------------
左へ進む
止まる
-----------------
名前:Rワゴン
ナンバー:7890
ガソリン:50
ボディー色:red
-----------------
前へ進む
止まる
-----------------
名前:タスカン
ナンバー:6543
ガソリン:50
ボディー色:orange
-----------------
後ろへ進む
止まる

上記、コンストラクタB、C、Dが実行されると、コンストラクタAが実行される仕組みになってます。

この「this()」という書き方は、コンストラクタの中だけで使えます。

また、コンストラクタ定義の中で、this()一行目に書かねばならないという規則があります。

以下のような書き方はできないので、注意してください。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Car
package chapter6;

/**
* 車機能を持ったクラス
* @version 1.0
* @author Yamamoto
*/
public class Car{

/**
* 車の名前を保持
*/
String carName;

/**
* 車のナンバー情報を保持
*/
int number;

/**
* 車のガソリン(ℓ)の量を保持
*/

int gass;

/**
* 車のボディー色を保持
*/
String bodyCorlor;

/**
* コンストラクタA
*/
public Car(String carName, int number, int gass, String bodyCorlor){

this.carName = carName;
this.number = number;
this.gass = gass;
this.bodyCorlor = bodyCorlor;
System.out.println("CarクラスのコンストラクタAを実行");
}

//-----ここから(修正)-----

/**
* コンストラクタB
*/
public Car(String carName, int number, int gass ){

System.out.println("CarクラスのコンストラクタBを実行");
this(carName, number, gass, "white"); //コンストラクタAを実行

}

/**
* コンストラクタC
*/
public Car(String carName, int number ){

System.out.println("CarクラスのコンストラクタCを実行");
this(carName, number, 50, "red"); //コンストラクタAを実行

}

/**
* コンストラクタD
*/
public Car(String carName ){

System.out.println("CarクラスのコンストラクタDを実行");
this(carName, 6543, 50, "orange"); //コンストラクタAを実行

}

//-----ここまで(修正)-----

/**
* 走行
* @param direction String型 走行方向
* @return 無し
*/
public void goRun(String direction) {
gass--;
System.out.println( direction + "へ進む" );
}

/**
* 停止
* @param 無し
* @return 無し
*/
public void stop() {
System.out.println( "止まる" );
}

/**
* 車データ情報表示
* @param 無し
* @return 無し
*/
public void disp() {

System.out.println( "-----------------" );
System.out.println( "名前:" + this.carName );
System.out.println( "ナンバー:" + this.number );
System.out.println( "ガソリン:" + this.gass );
System.out.println( "ボディー色:" + this.bodyCorlor );
System.out.println( "-----------------" );

}

}

コンパイル例:

> javac chapter6¥Car.java
chapter6/Car.java:51: エラー: thisの呼出しはコンストラクタの先頭文である必要があります
this(carName, number, gass, "white"); //コンストラクタAを実行
^
chapter6/Car.java:61: エラー: thisの呼出しはコンストラクタの先頭文である必要があります
this(carName, number, 50, "red"); //コンストラクタAを実行
^
chapter6/Car.java:71: エラー: thisの呼出しはコンストラクタの先頭文である必要があります
this(carName, 6543, 50, "orange"); //コンストラクタAを実行
^
エラー3個

※上記はthis()を使用したコンストラクタを1行目で書いてないので、コンパイルエラーが発生します。

メソッドのオーバーロード

メソッドもオーバーロードとして同じ名前を持つ複数のメソッド定義することができます。

メソッドのオーバーロード引数リストの構成(引数の型の並び順)が異なる必要があります。
なお、戻り値やアクセス修飾子は自由に変えることが可能です。

例題(メソッドのオーバーロード)

以下クラスを作成し、実行結果を確認してみましょう。

項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 Score
package chapter6;

/**
* 点数を表すクラス
* @version 1.0
* @author Yamamoto
*/
public class Score{

/**
* 合格ライン点数を保持
*/
String mastScore;

/**
* コンストラクタ
*/
/**
public Number(int mastScore){
this.mastScore = mastScore;
}

* 点数チェック(int型)
* @param score 点数
* @return 合否有無
*/
public boolean isCheckScore(int score) {
return mastScore <= score;
}

* 点数チェック(double型)
* @param score 点数
* @return 合否有無
*/
public boolean isCheckScore(double score) {
return mastScore <= score;
}

}
項目 名前
プロジェクト alj_study
パッケージ chapter6
クラス名 NumberCheckExec
package chapter6;

/**
* 実行する為のクラス
* @version 1.0
* @author Yamamoto
*/
public class NumberCheckExec{

/**
* mainメソッド
*/
public static void main(String[] args) {

Score s = new Score(400);

boolean ans1 = s.isCheckScore(500);
boolean ans2 = s.isCheckScore(345.6);

System.out.println(ans1);
System.out.println(ans2);

}
}

コンパイル例:

> javac chapter6¥Score.java
> javac chapter6¥NumberCheckExec.java

実行例:

> java chapter6.NumberCheckExec
true
false

Scoreクラスは点数判定をおこなうクラスです。isCheckScore()メソッドは、合格ライン点数データを保持している変数mastScore以上の場合trueを返します。メソッドはint型とdouble型用をオーバーロードで定義しています。

章のまとめ

以下の要点を理解できたら次の章へ進んでください。

オブジェクト指向

  • オブジェクト指向とは、現実世界に存在する「もの」を中心にモデル化する考え方
  • オブジェクトとは「もの」という意味を持ち、現実世界に存在するさまざまな事柄を指す
  • オブジェクトには、実際に目に見えるもの抽象的な事柄も含まれる
  • モデル化とは、複雑なものや事柄をわかりやすい形に表現する方法
  • プログラムの部品化規格化ができる、汎用システムを作成できる

クラスとオブジェクト

  • オブジェクトを作成するためには、オブジェクト設計図を作成しなければない
  • Javaではオブジェクトの設計図のことをクラスという
  • 設計図(クラス)があれば、同じものを必要に応じていくつでも作ることができる
  • クラスには、オブジェクトに必要な属性(プロパティ)操作定義する
  • 属性とは、オブジェクトの特性状態を表すデータ(情報)にあたるもの
  • 操作とは、オブジェクトの動作振る舞いを表す処理にあたるもの
  • オブジェクトとはクラス(設計図)をもとに生成される実体である
  • オブジェクトはクラスに定義された属性としてのデータ操作としての処理保持する
  • 1つのクラスから複数のオブジェクト生成することができる

クラスの作り方

[メンバ変数の定義]

[ 修飾子 ]  データ型 変数名;

  • 属性(プロパティ)定義する際は変数(メンバ変数)宣言する
  • メンバ変数のことを別名フィールドとも呼ぶ
  • 修飾子にはアクセス修飾子static修飾子final修飾子を指定する

[メンバメソッドの定義]

[修飾子] 戻り値の型 メソッド名(引数リスト) {
//処理(操作内容)
}

  • 操作定義する際はメンバメソッド(メソッド)という形でクラスへ定義する
  • メンバメソッド定義方法は、メソッド定義方法と同じ(以下参照)

  • 修飾子にはstatic修飾子アクセス修飾子final修飾子を付与することができる

  • 戻り値とは呼び出し元のメソッドへ返す値(データ)のこと
  • 戻り値の型には、呼び出し元のメソッドに返す値のデータ型を指定する
  • 値を返さないメソッドの場合は、戻り値の型にvoidを指定する
  • 引数リストは呼び出し元のメソッドから渡されるデータ受け取る変数のこと
  • 引数リストは仮引数ともいわれており、変数の宣言を記述する
  • メソッドを終了する命令return文という
  • 戻り値があるメソッドの場合には returnの後値(データ)の記述が必須である

オブジェクトの作り方

  • クラスをもとにオブジェクトを生成することをインスタンス化という
  • インスタンス化するためにはnew演算子を使う
  • new演算子を使うと、ヒープと呼ばれる記憶領域オブジェクトが作成される
  • オブジェクト利用するためには、クラス型変数宣言し、代入しておく必要がある
  • オブジェクト作成した直後メンバ変数には既定値が入る
  • 整数型には既定値として0が代入されている
  • 浮動小数点型には既定値として0.0が代入されている
  • 文字型には既定値として¥u0000が代入されている
  • boolean型には既定値としてfalseが代入されている
  • 配列型クラス型には既定値としてnullが代入されている

オブジェクトの使い方

  • オブジェクトのアドレスが代入してある変数メンバ変数名ドット( . )で繋ぐと特定のメンバアクセス(参照)することができる。ドット( . )のことをメンバー演算子という。
  • メンバ変数データ(値)代入する場合は「変数.メンバ変数名 = 値;」と指定する
  • インスタンス化した直後メンバ変数は、既定値代入されている
  • メンバ変数データ(値)代入していない状態メンバ変数参照すると既定値表示される
    参照型の場合はnull表示される)

コンストラクタ

  • コンストラクタとは、インスタンス化する際に実行される初期化処理のこと
  • コンストラクタを明示的に定義すると、メンバ変数特定の値を代入することができる

[コンストラクタの定義]

[ 修飾子 ] class クラス名  {
[ 修飾子 ] コンストラクタ名(引数リスト) {
//インスタンス化する時に実行される処理
}
}

  • コンストラクタ名クラス名同じにしなければならない
  • コンストラクタには、戻り値型無い(voidも書かない)
  • public修飾子省略可能(同じパッケージ内での利用のみ)
  • 引数リスト並び順個数メンバと違っていても良い
  • return文以外なら任意の文を書いても良い

[コンストラクタの利用]

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

  • コンストラクタnew演算子とセットで利用する
  • 引数リストを設定するとき、コンストラクタの定義通り設定する
    並び順個数同じでなければならない)
  • コンストラクタ引数名は、メンバ変数名同じにすることが推奨されている
  • thisキーワードは、メンバ変数と、その他の変数(引数など)区別する時に使うことができる
  • thisキーワードは、コンストラクタメソッドで使用することができる
  • メンバ変数直接リテラルを設定することも可能
  • コンストラクタ内return文以外であれば、通常の処理記述することが可能

コンストラクタのオーバーロード

  • コンストラクタ役割は、メンバ変数初期値設定することである
  • 引数の数が違う引数の並び順が違う引数の型が違う場合、コンストラクタ複数定義することが可能(コンストラクタのオーバーロード)

  • プログラマがコンストラクタを1つも定義しない場合、コンパイラが自動でコンストラクタを定義する(デフォルトコンストラクタ)

  • デフォルトコンストラクタは、引数がなく何も処理しないコンストラクタである
  • コンストラクタプログラマが作成すると、デフォルトコンストラクタ作成されない

  • プログラミングは、同じ処理何度も書かないこと、一箇所にまとめることが一般的である

  • 自身のコンストラクタ呼び出したい場合は、this(引数リスト)を指定する
  • コンストラクタ定義の中で、this(引数リスト)一行目に書かねばならない

メソッドのオーバーロード

  • メソッドオーバーロードとして同じ名前を持つ複数のメソッド定義することができる
  • メソッドオーバーロード引数リスト構成(引数の数や型の並び順)異なる必要がある