みなさまこんにちは。
Numata です。
記事を読んで、
参考になった!
疑問を解決できた!
何言ってるかわからなかった!!
結局疑問のままだった!!
などなど、感想をいただければ幸いです。
それでは参りましょう。
コンストラクタってやつに苦戦してこの記事に辿りついていると思います。
この先、オブジェクト指向を扱っていくなかで、コンストラクタの概念は必須です。
インスタンスと密接に関わっているため、正しく理解して
使いこなせるようにしましょう!
もくじ
コンストラクタはインスタンス化するとき、必ず最初に処理されるメソッドです。
まず注意すべきは、コンストラクタはメソッドの一種だということです。
コンストラクタという、全くの新種な機能・部品というわけではなく、
あくまでも、メソッドの一種なのです。
普通のメソッドの親戚のようなイメージです。
コンストラクタがやることは、
”呼ばれたら、{} の中の処理を行うこと” です。
メソッドと全く同じですね。
もちろん引数ももらうことができます。
まずは、コンストラクタはメソッドの一種だということを念頭に置いてください!
では、どのように違うのでしょうか。
コンストラクタはインスタンス化(new)されるときに必ず最初に実行されます。
これが通常のメソッドとの違いです。
メソッドはクラスがインスタンス化された後に、メソッドを呼ばれて初めて実行されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Human { String name; String address; int age; int birthDay; public void hello(String name) { System.out.println(name + "さん。おはようございます!" + this.name + "です。"); } } |
1 2 3 4 5 6 7 |
public class Main { public static void main(String[] args) { Human human = new Human(); human.hello("たろう"); //ここで初めて実行される } } |
一方コンストラクタは、インスタンス化されるときに実行されるので4行目で実行されます。
1 2 3 4 5 6 7 |
public class Main { public static void main(String[] args) { Human human = new Human(); //ここで実行される human.hello("たろう"); } } |
実行されるタイミングはお分かりいただけたでしょうか。
コンストラクタの宣言
次に宣言の仕方です。
コンストラクタの宣言は、
アクセス修飾子 クラス名 (引数) {処理}
です。
メソッドと違うのは、下記2点です。
①戻り値がないこと
②メソッド名=クラス名であること
それぞれ解説すると、以下のルールがあります。
①コンストラクタには、戻り値を書いてはいけません。
(書くとメソッドとして扱われてしまいます。)
②メソッド名をクラス名と同じにしなければなりません。
(違うとメソッドとして扱われてしまいます。)
このルールをもとに、先ほどのHuman クラスにコンストラクタを設置してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Human { String name; String address; int age; int birthDay; //コンストラクタ public Human(String name) { this.name = name; } public void hello(String name) { System.out.println(name + "さん。おはようございます!" + this.name + "です。"); } } |
今回は引数に受け取った値をnameフィールドに代入する
という処理のコンストラクタを設置しました。
コンストラクタの実行のされ方
改めてインスタンスを作ってみましょう。
コンストラクタの実行には、new 演算子の隣の()に引数を渡します。
1 2 3 4 5 6 7 8 9 |
public class Main { public static void main(String[] args) { Human human = new Human("はなこ"); //コンストラクタにはなこを渡す human.hello("たろう"); } } →たろうさん。おはようございます!はなこです。 と出力される |
コンストラクタの
宣言方法・実行のされ方 は以上です!
・コンストラクタの宣言
アクセス修飾子 クラス名 (引数) {処理}
ex) public Human (String name) {省略}
・実行のされ方
インスタンスを作るとき、new演算子の隣の()に引数を渡す
もし、コンストラクタがなぜnewのタイミングで実行されるの?と疑問を感じた方は
Javaのルールで決まっている。と覚えてください。
Javaの中では、なぜ?を追求すべきところとそうでないところがあります。
コンストラクタの起動は追求しなくてよいところです。ルールとして覚えましょう!
コンストラクタの重要ルール
コンストラクタにはほかにも注意すべき重要ルールが3点あります。
[コンストラクタの重要ルール]
①コンストラクタは書いていなくても、自動でデフォルトコンストラクタが作成される
②コンストラクタはいくつ書いても良い
③複数のコンストラクタが存在するとき、該当する一つのみが処理される
④継承しているクラスの場合、親クラスのコンストラクタが必ず処理される
①コンストラクタを書いていなくても、 自動でデフォルトコンストラクタが作成される
今まで、コンストラクタを書いていないクラスをnewしたことがあると思います。
ですが、Javaには、「インスタンス化されるとき、コンストラクタが実行される」
というルールが存在しています。
存在しないものを実行するなんてことは不可能ですね。。
この矛盾を解決してくれるのが、デフォルトコンストラクタです。
デフォルトコンストラクタとは、コンストラクタが明記されていないとき、
コンパイラーが勝手にクラスに付け加えてくれるコンストラクタです。
例えばこのようなクラスがあった場合
1 2 3 4 5 6 7 8 9 10 11 |
public class Slime { String name; int power; int defense; public int attack() { System.out.println("スライムの攻撃力は" + this.power + "だ!"); return this.power; } } |
デフォルトコンストラクタはこのように自動で設置されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Slime { String name; int power; int defense; //デフォルトコンストラクタ public Slime() {} public int attack() { System.out.println("スライムの攻撃力は" + this.power + "だ!"); return this.power; } } |
デフォルトコンストラクタは、
クラスと同じアクセス修飾子 クラス名 (){}
ex) public Slime () {}
と勝手に作成されます。
引数と処理を持たないコンストラクタです。
これにより、インスタンス化されるとき
必ずコンストラクタが実行されるというルールをクリアすることができます。
コンストラクタが明記されていないときは、
デフォルトコンストラクタが自動作成されます!
②コンストラクタはいくつ書いても良い
コンストラクタは複数存在することができます。
メソッドのオーバーロードの要領と全く同じです。
引数の個数や種類を変えることで、いくつでも作成することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class Slime { String name; int power; int defense; //コンストラクタ①:nameは必ず持つインスタンスにする public Slime(String name) { this.name = name; } //コンストラクタ②:powerは必ず持つインスタンスにする public Slime (int power) { this.power = power; } //コンストラクタ③:nameとdefenseは必ず持つインスタンスにする public Slime(String name, int defense) { this.name = name; this.defense = defense; } public int attack() { System.out.println("スライムの攻撃力は" + this.power + "だ!"); return this.power; } } |
③複数のコンストラクタが存在するとき、 該当する一つのみが処理される
インスタンス化するときは、いずれかのコンストラクタと合致する引数を渡しましょう。
1 2 3 4 5 6 7 8 9 10 |
public class Main { public static void main(String[] args) { Slime slimeA = new Slime("スライムA"); //①コンストラクタ Slime slimeB = new Slime(100); //②コンストラクタ Slime slimeC = new Slime("スライムC",10); //③コンストラクタ Slime slimeD = new Slime(); //コンパイルエラー } } |
コンストラクタは複数存在できます。
存在するいずれかのコンストラクタに合致するインスタンス化の式を書きましょう。
ただし、コンストラクタが一つでも明記されていると、
デフォルトコンストラクタは自動作成されません。
なじみのある8行目のインスタンス化はコンパイルエラーになるので注意してください。
コンストラクタが一つでも明記されているとき、
デフォルトコンストラクタは発生しません!
④継承しているクラスの場合、 親クラスのコンストラクタが必ず処理される
インスタンス化したいクラスが、継承クラスの場合、
子クラスのコンストラクタの中で、親クラスのコンストラクタが処理されます。
これはとても複雑な処理です。
また別記事を作成して説明します。
↓記事作成しました!
コンストラクタはインスタンス化とセットです
コンストラクタとインスタンス化は必ずセットで覚えましょう。
コンストラクタの動きによって、作られるインスタンスも変わってきます。
newされる時は、必ずコンストラクタが実行されている
ということを忘れないように、常に注意しましょう。
ご覧いただき、ありがとうございました。
コンストラクタはインスタンス化するときに必ず実行されるメソッドです!
大切なことなので、最後にもう一度言いました。笑
コンストラクタは、明記してあることを見逃しがちなので、
引数なしのインスタンス化(new 型名();)をしようとして躓いたときは、
冷静になって振り返ってみてください!
以上です。
最後までご覧いただき、ありがとうございました。
コメント