はじめに
今回扱うもの
- メソッド
- 継承
- インターフェース
前回の「コンストラクタ」同様、オブジェクト指向に関する場所なので分かりづらい。例を挙げながらつらつらと記述していく。part3までは読んでね。
今回の部分まで理解できると違う言語でもプログラミングしやすくなり、とても便利な考え方です。がんばりましょう。
メソッド
ここではオブジェクト指向で超重要な部分、メソッドについてお話する。
メソッドとは、自分が作成したオブジェクトに対して「どんな挙動をするか」を記述する部分である。「ノートPC」というオブジェクトを作った場合、コンストラクタでは「誰の」や「色」、「ハード構成」のような物体そのものに対して記述していく。対してメソッドは「起動する」「ネットワークにつなぐ」「ファイルを圧縮する」のような行動・状態遷移を定義できる。
public class Car
{
int number;
String owner;
int speed;
public Car()
{
this(0000, "None", 0);
}
public Car(int number, String owner, int speed)
{
this.number = number;
this.owner = owner;
this.speed = speed;
}
void info()
{
System.out.println("ナンバー:" + this.number);
System.out.println("所有者:"+ this.owner);
System.out.println("速度:"+ this.speed);
}
}
public class Main
{
public static void main(String[] args)
{
Car car1 = new Car(1234, "高橋", 40);
car1.info();
Car car2 = new Car();
car2.info();
}
}
今回は車を2台作成した。1つは簡易的に所有者を決めたもの、もう1つは何も設定していない車だ。
Main.javaの「~.info();」でCar.javaの「void info()」が呼び出され、順番に実行される仕組みになっているので、informationとして全情報が出力された。
オブジェクトがメソッドを呼び出す際には「car1.info()」のように、変数名のあとに「.」、呼び出したいメソッドを記述して呼び出す。コンストラクタと同じように、呼び出すメソッドに引数がある場合はちゃんと引数も入れよう。
...
ちょっと待ってほしい。
part3を振り返ってみよう。
『ファイルへの計算の受け渡しだが、別ファイルで書いた「int math(int num1, int num2)」という部分をMainファイルで呼び出すことで実行』
そう、あなた方はすでに「戻り値があるメソッド」を書いている。
オブジェクト指向を取り入れても、基本的には何も変わっていない。**「オブジェクトだけが実行できるメソッド」なのか「main関数自体が実行するメソッド」**しか変化していない。
メソッドはオブジェクトの挙動、ある意味**「特性」を書いている部分なので、複数個のオブジェクトで呼び出しても挙動は一緒**、という点がメリットだろう。この部分は次に扱う継承とインターフェースで役に立つ。
ここのまとめ
- メソッドとは?
- オブジェクト指向ではどんな働きをするの?
- どんなメリットがあるの?
継承
の前に...
本当はすぐ継承を書きたかったのだが、触れていない構文で継承とかやる上でめっちゃ便利なものを触れます。
配列です。まだやってなかった。
言葉の意味の通り「最初から最後まで1列に並んでいる配列群」です。ただしちょっとめんどくさい部分もあるので丁寧に行きます。
public class Array
{
public static void main(String[] args)
{
int[] array = {1, 3, 5, 7, 9};
/*
↓これと同じことを1行で行っている
int array[] = new int[5]; //オブジェクトの構文
array[0] = 1;
array[1] = 3;
array[2] = 5;
array[3] = 7;
array[4] = 9;
*/
for(int i = 0; i < array.length; i++) //array.lengthは配列の長さを表している
{
System.out.println((i+1) + "個目の数:" + array[i]);
//for文で5行分のprintlnを回している
//array[i]とすることで、要素の最初から出力できる
}
}
}
配列って、要素の番号(array [?]のことやで)の最初の数字が0からだから分かりづらい。そういうもんだと割り切ってほしい。
オブジェクトとほぼ一緒の構文なのだが、名前に[ ]がつくことが相違点。**型が「int[ ]」**ってだけ。もちろんdoubleでもStringでも良いし、オブジェクトも入れられる。
1行で書く書き方だと「 [ ] 」は型につくので注意。
for文の中身は単純に配列の中身を出力したいだけである。**「.length」**をつかってバグがなるべく出ないようにはしている。
これ何かというと、配列の長さを指定しなくてもJavaが勝手に配慮してくれている。例えば、複数の配列を使ってデータを管理したいとき、要素が違うだけで同じ構文をコピペするのはファイルが長くなって見づらいじゃん。そんなときにこれを知っているだけで、メソッドとして定義しておけば一発で全部配慮して実行してくれる。便利。
これを踏まえて継承やりましょうか。
継承
まず継承をJavaで説明する前に、継承の考え方を伝える。
継承とは、「自分の子に動作や特性を持たせる」ことである。
具体的に言うと、親である「自動車」は走ったり静止でき、重量があり大きい。そして継承をした「スーパーカー」は走る速度がめっちゃ速く、重量は少し軽くなり大きい。
このように、一部の機能や特性を保持しつつ改良された子のことをサブクラスと呼び、その親のことをスーパークラスと呼ぶ。
今回も車を作成し、それを継承するスーパーカーを作成し説明させていただく。
public class Car
{
double weight;
int speed;
Car()
{
this(0.0, 0);
}
Car(double weight, int speed)
{
this.weight = weight;
this.speed = speed;
}
Car(int speed, double weight)
{
this(weight, speed);
}
void drive()
{
System.out.println("時速" + this.speed + "で走行した");
}
void info()
{
System.out.println("重さは" + this.weight + "kgです");
System.out.println("速度は" + this.speed + "です");
}
}
public class SuperCar extends Car
{
int max_speed;
SuperCar()
{
this(0, 0, 0);
}
SuperCar(double weight, int speed, int max_speed)
{
super(weight, speed);
this.max_speed = max_speed;
}
void CarChase()
{
System.out.println("時速" + max_speed + "でカーチェイスしました");
}
void info()
{
super.info();
System.out.println("最高速は" + max_speed + "です");
}
}
public class Main
{
public static void main(String[] args)
{
Car normal = new Car(200.0, 40);
SuperCar superCar = new SuperCar(180.0, 50, 200);
superCar.drive(); //書いてないのに呼び出せる!
System.out.println("\n");
superCar.info();
}
}
今回は車の要素をスーパーカーで継承し、親クラスのメソッドをサブクラスで呼び出した。Java(というかオブジェクト指向)では親より子のほうが優秀なのだ。
また、子クラス独自のメソッドやコンストラクタを作成し、親クラスの内容を子クラス用に手直しすることも可能だ。親クラスの内容をそのまま呼び出したいときは「super」を用いる。
ここのまとめ
- 継承ってどんなの? -> 親から子に伝承すること
- 親とは?子とは? -> 伝承されたクラスは「子」
- 「super」ってなに? -> 子が親を呼び出すときに必要