はじめに
part1, 2を読んでから見よう。須く。
今回からオブジェクト指向、クラス等分かりづらい部分を触れるので気合い入れて行きましょう
ファイルを分ける
Javaではオブジェクト指向型を採用しており、初心者が理解するときの壁になっている。概要から申し上げると、「この世のモノ全部オブジェクト(物体)でしょ?」といった考え方である。具体例を出すと、「食べ物」は抽象的な概念でモノとしてはいっぱい種類があるが、「カレーライス」は一般的に固定のモノとして存在している。これらを「オブジェクト」と呼んでいるにすぎないのだ。
じゃあどうやって書くんじゃ
オブジェクト指向を記述する上で、まずJavaで複数のファイルを扱う方法を記述する。これはファイルごとにどんなものを記述しているか大まかに分けたいからだ。
以下はキーボード(標準入力)で読み取った数字を計算させるプログラムで、ファイルを分けて計算処理だけを別ファイルに保存している。
//大まかな処理を記述しているファイル
import java.io.*;
public class Main
{
public static void main(String[] args)throws IOException //例外処理
{
BufferedReader br = //改行しないでも良い
new BufferedReader(new InputStreamReader(System.in));
int num1, num2; //あとで数字を代入する変数たち
int ans; //答えを代入する変数
System.out.println("足したい数字を2つ、入力してください");
System.out.print("1つ目>"); //printlnは改行するが、printは改行しない
String str1 = br.readLine();
num1 = Integer.parseInt(str1);
System.out.print("2つ目>");
String str2 = br.readLine();
num2 = Integer.parseInt(str2);
System.out.println("mathematics.javaの呼び出し\n"); // \nは改行するコード
ans = math(num1, num2); //計算を別ファイルに任せて代入
System.out.println("計算結果>" + ans);
br.close(); //brの終了宣言
}
}
ここからは別ファイルでの処理
class mathematics
{
int math(int num1, int num2) //詳細は下で。math関数を定義している
{
int ans;
ans = num1 + num2;
return ans; //returnはもとのファイルに送信する文
//この3行をまとめて「return (num1 + num2);」でも良い。()もいらないかもしれないがわかりやすいので記述
}
}
これを実行すると、2つの数字を計算した結果が表示されるはずだ。
今回はファイルを分ける際、mathematics.javaの中で「public static void main(String[] args)」という構文を書いていないが、これは実行する専用のファイルを表しているからだ。Main.javaは実行するファイルのため、明記している。
そしてファイルへの計算の受け渡しだが、別ファイルで書いた「int math(int num1, int num2)」という部分をMainファイルで呼び出すことで実行できるようになる。
別ファイルで「int num」のように、呼び出したい型の種類と名前(違う名前も可、非推奨)を書くことでmath関数の中でも呼び出せるようになる。これを引数という
そしてmath関数最後にある「return」は、もとのMain関数に答えを返し、処理もMainに移す処理である。この値を戻り値という。mathematics.javaで書いた「int math(int ...)」の最初のintは戻り値をintにするという意味がある。
もう一度振り返り、2つのファイルを見てほしい。最初に見たときより構文が「見える」んじゃないだろうか。
ここのまとめ
- 複数のファイルでJavaをかける
- 引数って?
- returnって?
- int型の戻り値を指定したいときは?
#オブジェクト指向プログラミング
本題ですね。
オブジェクトとは、さっき言ったカレーのことである。うどんとかお茶でも、全部がオブジェクト。
Javaに限らず、関数と同じ感覚で自由な型を作り自由な値を入れられるものがオブジェクトであり、幅広い処理を作れるのでとても便利。
まずは構文から。このあたりからJavaファイルは基本的に1つではありません。
public class Car
{
String carName; //車種
String companyName; //会社名
double weight; //重さ
int number; //ナンバー
Car(String carName, String companyName, double weight, int number) //引数が4つある
{
this.carName = carName; //thisの詳細は後で。
this.companyName = companyName;
this.weight = weight;
this.number = number;
}
}
ここまでは「車」型を作るjavaファイル。次は実行できるMainファイルを作成。
public class Main
{
public static void main(String[] args)
{
System.out.println("今から「車」型を呼び出してNISSANリーフを作成します");
String carName = "リーフ";
String companyName = "NISSAN";
double weight = 1600.0;
int number = 1234;
Car car1 = new Car(carName, companyName, weight, number);
//CarファイルのCar(引数4つ)
System.out.println(car1.Name + "を呼び出しました");
//変数名のあとに「.」をつけて呼び出したい項目を書く
}
}
今回は日産リーフを作成、呼び出したことを確認する構文を用意した。1つずつ見ていこう。
Car.javaに書いてある構文から説明する。
class Carのあとに用意したい項目を記述している。重要なのはこのあとからで、Car()と記述している部分で「this」なるものが記述されている。これは自分自身の参照をしていて、CarNameが引数なのか、それともCar.javaで用意した変数なのかの区別に使われている。今回でいうと、thisがついているのはCar.javaで用意した変数を参照している。引数は関数の処理が終わると保存されずに消えてしまうので、関数内で保存した、というわけである。
Main関数内を見てみよう。
今回、新しく「new Car(省略)」という構文が出てきている。これが再三申し上げている「オブジェクト」だ。今回で説明すると**「Car型のcar1の名前やナンバーはCar(省略)で決めます!」という構文だ。そして呼び出された瞬間、Car.javaで代入が行われ、処理が保存されてMain関数内に戻ってくる**、といった寸法である。
そしてここには落とし穴があり、「順番通りに記述しないとバラバラの変数に代入されてしまう」のだ。
例えばMain内で「new Car(companyName, carName, ...)」などと記述してしまった瞬間、会社名と車種が入れ替わってしまう。Car.javaでも同じ順番で記述しなければならない。
さらに、**現段階では「4つの引数の車しか作成できない」**のである。例えば「車の重さなんていらねぇ!俺は書かないぞ!」とはできないのである。
これを回避するには、追加で3つの引数を持つ構文を書くしかない。
...でもめんどいよね?わざわざ全通り中身書くの。
中身だけならある程度サボれます。バンザイ
やり方は簡単。下の構文を見てほしい。
//省略
//さっき書いた構文
Car(String carName, String companyName, double weight, int number) //引数が4つある
{
this.carName = carName; //thisの詳細は後で。
this.companyName = companyName;
this.weight = weight;
this.number = number;
}
Car(String carName)//車種だけとりあえず決める構文
{
this(carName, "未定義", 0.0, 0); //4つの引数の構文に処理を渡す
}
このように、Carの引数が1つだけでも中で4つの引数の部分を呼び出すことで楽ができる(し、ミスが減る)
今回のような**「型をきめる関数」を特に「コンストラクタ」**と呼び、**2つ以上の組み合わせがあるコンストラクタたちの中から1つを呼び出すことを「オーバーロード」**と呼ぶ。
###ここのまとめ
- オブジェクト指向とは
- 自由な型、自由な処理
- thisとは
- コンストラクタ
- オーバーロード