【Java入門(2)オブジェクト指向:基本編 #5】コンストラクタ

 

みのる
こんにちは。笑顔で感謝!✨ みのるコーチです。
今回も、ご覧いただき、ありがとうございます。

今回は

Java入門2 オブジェクト指向:基本編 #5
コンストラクタ

というテーマでお送りします。

彩香
だんだん、オブジェクト指向プログラミングが
分かってきました。

今回も、新たな事を学ぶのが楽しみです。
よろしくお願いします。

剛留
インスタンス化して Java仮想世界を作っていくこと
とても面白いと思いました。

用語も たくさん出てきていますが
今回も、ガッツリ頑張ります。

【Youtube版】

Youtubeでもお伝えしていますので
是非チェックしてくださいね。

【1】 コンストラクタ

設計図となるクラスには、2つのメンバ
フィールド と メソッド を定義するとお伝えしました。

そして今回は、もう1つのメンバを見ていきましょう。

コンストラクタというもので

クラスが インスタンス化される時に
実行されるメンバです。

コンストラクタ
クラスがインスタンス化される時に
実行されるメンバ。

コンストラクタの中には、フィールドの初期化など
インスタンス化される時に 実行したい処理を記述します。

コンストラクタは、Javaソースファイル中で
一般的に、このように配置されます。

1つの Javaソースファイルの中に
クラスを 1つ 記述して

まずは、フィールドを記述します。

その次に、コンストラクタを記述して。

その後に、メソッドを記述することとなります。

ここでは、Javaのクラスの中での 3つのメンバの配置を
ザックリ 押さえておきましょう。

【2】 コンストラクタ定義

コンストラクタはこのように定義します。

コンストラクタ定義
コンストラクタ名(データ型 仮引数,…) {
    処理ブロック
}
彩香
ほとんど、メソッドと同じように見えるんですが
メソッドの「いとこ」みたいな感じですか…?
みのる
良い 気づきですね~。

メソッドの 「 いとこ 」 かどうかは分かりませんが…

仮引数を受け取れるところや、処理を行うブロックが
あるところは メソッドに似ていますね…。

ただ、普通のメソッドとは、このような違いがあります。

コンストラクタ
❶ コンストラクタ名はクラス名と同じ。
❷ 戻り値なし。
❸ 実行されるのはインスタンス化される時。

【例】を見てみましょう。

前回に引き続き、営業部員を表す SalesEmployee クラスです。

public class SalesEmployee {
        String name;
        int salesAmt;

        SalesEmployee(String n, int a) {
        name = n;
        salesAmt = a;
    }

    // この後にメソッド…
}

クラスの中で
最初にフィールドが、2つ定義されています。

名前を表す String型変数の name と
売上合計金額を表す int型変数の salesAmt です。

そして、その次にコンストラクターの記述です。

コンストラクタ名 SalesEmployee は クラス名と
同じですね。

仮引数を2つ受け取っています。

フィールドを初期化するための…

名前を表す String型引数の n と
売上合計金額を表す int型引数の a です。

戻り値はありません。戻り値の型 void も書きません。

そして処理ブロックの中では、フィールドの値の
初期化を行っています。

フィールド name に 引数 n を代入して
フィールド salesAmt に 引数 a を代入しています。

このように、フィールドの初期化などが
行われる場合が多いものです。

剛留
前回は、クラスの中に コンストラクタは
書かなかったんですが…。

コンストラクタは、無くてもいいんですか?

みのる
勉強したところを 繋げて考えていますね。
Goodですよ~。

そして、答えですが…

デフォルトコンストラクタ というものがあります。

これは…

クラスにコンストラクタの記述がない場合に
Javaで暗黙的に付加されるものです。

そして、「引数なし」「中身が空(処理なし)」の
コンストラクタです。

デフォルトコンストラクタ
・ クラスにコンストラクタの記述がない場合に
  Javaで暗黙的に付加される。

・ 「引数なし」「中身が空(処理なし)」の
  コンストラクタ。

前回の例では、SalesEmployeeクラスに
フィールド と メソッド だけを定義したので…

public class SalesEmployee {
    String name;
    int salesAmt;

    SalesEmployee() {
    }

    // この後にメソッド…
}

このように、Javaが 暗黙的に
デフォルトコンストラクタを 付加していたのです。

そして、1点 注意点があります。

この デフォルトコンストラクタは
コンストラクタが記述されていない場合に 付加されるもので…

実際に、コンストラクタが 記述された場合には
付加されないという事です。

この部分も、押さえておきましょう。

【3】 this.

this キーワードについて、見ていきましょう。

この this は、自身のインスタンスを
指し示すキーワードです。

this
自身のインスタンスを示す

この this の後に
ドット演算子とメンバ名を指定することで…

明示的に、自身のインスタンスのメンバに
アクセスすることが できます。

例えば 「 this.フィールド名 」 と書くと…

明示的に、自身のインスタンスの
フィールドにアクセスできます。

また

this.メソッド名(実引数,…) と書くと…

明示的に自身のインスタンスの
メソッドにアクセスできます。

例を 見てみましょう。

public class SalesEmployee {
    String name;
    int salesAmt;

    SalesEmployee(String name, int salesAmt) {
        this.name = name;
        this.salesAmt = salesAmt;
    }

    // この後にメソッド…
}

前のコーナーと同じ例ですが…

フィールド名は、name と salesAmt です

そして、コンストラクタの仮引数名も
同じ name と salesAmt にした場合です。

コンストラクタ内で、フィールドに値を代入する場合…

this.name = name;
this.salesAmt =salesAmt;

と記述します。

左辺の this.フィールド名 で、自インスタンスの
フィールドを明示的に表しています。

彩香
これ、this. をつけなかったら、どうなるんでしょう…?
みのる
色々なケースを探究すること、良いですね。
Goodです。
public class SalesEmployee {
    String name;
    int salesAmt;

    SalesEmployee(String name, int salesAmt) {
        name = name;
        salesAmt = salesAmt;
    }

    // この後にメソッド…
}

このように書いた場合ですね…。

フィールドのスコープは、クラス全体です。

仮引数のスコープは、コンストラクタ内です。

コンストラクタ内では、フィールド name も仮引数 name も
どちらも スコープですが…

このように 変数名が重複している場合には
内側の(狭い)範囲で 宣言されている 変数 を指します。

ですので、この場合には…

仮引数 name に 仮引数 name の値を代入し…

仮引数 salesAmt に 仮引数 salesAmt の値を
代入することになってしまいます。

つまり、フィールドに値を設定しない事に
なってしまうのです。

ですので、左辺は 自身のインスタンスの
フィールドと明示するために…

this をつける事が 必須になるのです。

剛留
フィールド名と仮引数名で、違う名前にすれば
this をつけなくて 大丈夫ですか?
みのる
良く見ていますね…

前のコーナーの例のように…
仮引数名を変えれば、this をつけなくても大丈夫です。

ただし、同じ項目を表す場合に 同じ名前をつける事が…
分かりやすさの面でも 多く使われます。

また、eclipseなどツールで
コンストラクタやメソッドを自動生成する時にも…

同じ項目には 同じ名前がつけられる
パターンが多いものです。

ですので、この部分は
ぜひ押さえておいてくださいね。

【4】 インスタンス化

クラスから実体のオブジェクトを作成することを
インスタンス化といいますが…

このインスタンス化は

① new演算子を用いてメモリ領域を確保

して…

② コンストラクタを実行

することで実現します。

インスタンス化
① new演算子を用いてメモリ領域を確保
② コンストラクタを実行

そして この時、クラスを利用する側では
このように記述する事になります。

インスタンス化して変数に代入
クラス名 変数名 = new クラス名(実引数,…);

※「実引数,…」はコンストラクタへの実引数。

前回 お伝えした時には、この「実引数,…」の部分が
無しだったという事になります。

前回は、クラスの定義の中で
コンストラクタを定義しなかったので…

デフォルトコンストラクタが 暗黙的に付加され
それを 呼び出していたからなんです。

クラスで、仮引数ありの コンストラクタを定義した場合には
その仮引数ありのコンストラクタを 呼び出す事となります。

例を 見てみましょう。

public class SalesEmployee {
    String name;
    int salesAmt;

    SalesEmployee(String name, int salesAmt) {
        this.name = name;
        this.salesAmt = salesAmt;
    }

    // この後にメソッド…
}

このクラスを インスタンス化する場合には…

SalesEmployee se
= new SalesEmployee(“速水剛留”, 1000000);

と記述する事になります。

イメージを再確認しておきましょう。

クラスをインスタンス化するときの記述方法は…

クラス名 変数名 = new クラス名(実引数,…);

となります。

内部的には…

① new演算子を用いてメモリ領域を確保

して…

② コンストラクタを実行

することで実現しています。

この イメージ も、押さえておきましょう。

【まとめ】

【1】 コンストラクタ
・ クラスがインスタンス化
  される時に実行されるメンバ。
【2】 コンストラクタ定義
・ 定義方法
  コンストラクタ名(データ型 仮引数,…) {
    処理ブロック
  }

・ コンストラクタ名は
  クラス名と同じ。

・ 戻り値はなし。
  void も書かない。

・ 定義しないと 自動的に
  デフォルトコンストラクタが
  付加される。

【3】 this.
・ this キーワードは
  自身のインスタンスを指し示す。

・ this.メンバ で、明示的に
  自身のインスタンスの
  メンバにアクセスできる。

【4】 インスタンス化
・ インスタンス化

  new クラス名(実引数,…)