Javaでオブジェクト指向をマスターしよう!-インスタンス編-
前回はクラスについて学習しました。
クラスはオブジェクトの設計図で、オブジェクト指向ではクラスを一つ一つ設計していくことが基本です。
今回は前回作成したHumanクラスを元に、インスタンスについて学習していきましょう。
なお、以下の実行環境を前提にしています。
OS:Windows 10 Pro
IDE:Eclipse 4.8 Photon(Pleiades)
Java:Java8
目次
1.インスタンス(Instance)
インスタンスは、日本語で「実体」と訳すのが最も適切です。
(1)インスタンスとは
前回学習したクラスは、オブジェクトの「設計図」であることは既にお話しした通りです。しかし、クラスは単なる設計図なので、それだけでは意味を持ちません。家を想像したら分かりやすいです。設計図だけあっても家を建てなければ設計した意味がありません。
この「家を建てる」という作業のことを、オブジェクト指向では「インスタンスを生成する」と言います。インスタンスを生成することで初めてクラスが意味を持ちます。
(2)インスタンスの生成
前回作ったHumanクラスを元にインスタンスを生成して、実体化したHumanから名前や年齢を聞いてみたいと思います。
mainメソッドに次のコードを入力して、実行してみてください。
public class Main {
public static void main(String[] args) {
Human itiro = new Human(); //…①
System.out.println(itiro.teachName()); //…②
}
}
インスタンスはnew演算子を使用して生成します。①で「itiro」インスタンスを生成しています。
ここで注目すべきは、HumanクラスがStringやIntegerのように「型」として使われている点です。Humanという型のitiro変数の中に、生成したHumanインスタンスが格納されているイメージです。
また②でitiroの名前を聞いてみました。System.out.printlnで結果をコンソールに出力していますが、実行すると次のように表示されます。
「私の名前はnullです。」
これはitiroインスタンスのnameフィールドがnullで暗黙的に初期化されているためです。次はフィールドの初期化方法を見ていきましょう。
(3)フィールド初期化方法①:コンストラクタ
コンストラクタとは、インスタンスを生成する際に呼び出されるメソッドのことです。
実際にコンストラクタを作成してみましょう。Humanクラスに次の記述を追加します。
public class Human {
String name;
double height;
double weight;
int age;
//コンストラクタ
Human(String name, double height, double weight, int age) {
this.name = name;
this.height = height;
this.weight = weight;
this.age = age;
}
(中略)
}
コンストラクタはクラス名と同じでなければなりません。this.nameやthis.heightなどの「this」は自身(つまりHumanクラス)のフィールドを指しています。コンストラクタ内で自身のフィールドに引数の値を格納して保持しています。
ここで先ほどのインスタンス生成を修正します。
public class Main {
public static void main(String[] args) {
Human itiro = new Human("鈴木一朗", 180.3, 79.4, 45);
System.out.println(itiro.teachName());
}
}
コンストラクタはインスタンスを生成するタイミングで呼び出します。実行してみましょう。次はこのように表示されます。
「私の名前は鈴木一朗です。」
クラス内のnameフィールドが初期化されたことで、ちゃんと名前を教えてくれるようになりました。ほかにも身長や体重も表示されるようになっているので、試してみてください。
(4)フィールド初期化方法②:setterメソッド
コンストラクタ以外にもsetterメソッドを作成してフィールドを初期化する方法もあります。
public class Human {
String name;
double height;
double weight;
int age;
void setName(String name) {
this.name = name;
}
void setHeight(double height) {
this.height = height;
}
void setWeight(double weight) {
this.weight = weight;
}
void setAge(int age) {
this.age = age;
}
(中略)
}
慣習的に、setterメソッドのメソッド名はset + フィールド名のキャメルケースです。setterメソッドでフィールドを初期化して、名前を教えてもらいましょう。
public class Main {
public static void main(String[] args) {
Human itiro = new Human();
itiro.setName("鈴木一朗");
System.out.println(itiro.teachName());
}
}
setName()で初期化しているので、「私の名前は鈴木一朗です」がコンソールに表示されます。
(5)インスタンスはいくつでも生成できる
インスタンスはクラスから何個でも生成することができます。つまり、同じ属性や操作を持った複数の実体を作れるということです。
例えばitiroのほかに、今度はhondaを追加してみましょう。コンストラクタで初期化します。
public class Main {
public static void main(String[] args) {
Human itiro = new Human("鈴木一朗", 180.3, 79.4, 45);
Human honda = new Human("本田圭佑", 182.0, 74.0, 32);
System.out.println(itiro.teachName());
System.out.println(honda.teachName());
}
}
これで新しく、Humanクラスのhondaが生成されました。コンソールには次のように表示されます。
2.まとめ
クラスが設計図なのに対してインスタンスは実体であることが今回のポイントです。同じクラスの型を持ったインスタンスを、いくつも作れるという点も今後重要になってくるので覚えておきましょう。
また、今回解説したフィールドの初期化方法ですが、実はコンストラクタやsetterメソッドを使わなくても、直接フィールドに値を格納することでも初期化は可能です。しかし、フィールドの値を直接設定、参照するのはオブジェクト指向では推奨されていません。そのあたりの話は、次回の「カプセル化」でお話しします。