通常表示 ]  [ 簡易表示 ]  [ シンプル表示 ]

「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典イメージぴよ画像「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典【簡易表示】

コンストラクタ (constructor)

pointこの用語のポイント

pointメソッド(関数)だよ

pointクラスをnewしたときに実行されるよ

pointオブジェクト指向なプログラミング言語で出てくるよ


コンストラクタ (constructor)とは

オブジェクト指向のプログラミング言語で登場する用語のひとつ

であり

インスタンスを作成したタイミングで実行されるメソッドのこと

です。
もう少しざっくり書くと

クラスをnewした瞬間に実行される関数のこと

です。
image piyo
さくっと一言で言ってしまえば「クラスnewしたときに実行される関数」が「コンストラクタ」です。

……と、いきなり言われても分かりませんよね。

大丈夫です。
順番に見ていきましょう。

まずは予備知識から行きます。

オブジェクト指向は「『モノ』に注目した考え方」です。
「どんな奴で、どう動く」に注目した考え方です。

コンストラクタ

オブジェクト指向の理念に沿って作られたプログラミング言語を「オブジェクト指向プログラミング言語」と言います。
有名どころでは、Javaなんかがオブジェクト指向プログラミング言語です。

オブジェクト指向プログラミング言語では「クラス」「インスタンス」「オブジェクト」という用語が頻繁に登場します。
この3つは、とても大事です。
ざっくりとで構わないので、関係性を覚えておいてください。

専門家の人からは怒られそうですが、ものすごい大雑把に説明すると

・クラス:設計図
・インスタンス:実際に作った物
・オブジェクト:モノ(クラスとかインスタンスとかをふんわりと表現したもの)


です。

クラスは「設計図」です。
「それってどんなもの?」を示しています。

インスタンスは「実際に作ったもの」です。
クラス(設計図)に書かれた「それってどんなもの?」を形にしたものです。

オブジェクトは……モノですよ、モノ。
結構ざっくりとした使われ方をする用語です。
「クラスとかインスタンスをふんわりと表現したもの」くらいに解釈してください。

オブジェクトについては、よく分からない人は忘れてしまって構いません。
コンストラクタを理解する上では、覚えていなくても支障はない用語です。

ざっくりと「クラス」「インスタンス」「オブジェクト」を理解できたでしょうか。

クラスは設計図です。
インスタンスはクラス(設計図)を実際に形にしたものです。
オブジェクトはクラスとかインスタンスをふんわりと表現したものですが、気にしなくて良いです。

コンストラクタ2

さて、ここからは少しプログラミング寄りの話になります。
Javaで書いたソースコードプログラムの元ネタ)を元にして見ていきましょう。

まずは最初の状態です。
Hello world」を表示するJavaのソースコードがありました。

public class test01{
    public static void main(String[] args){

        System.out.println("Hello World");

    }
}


ここにクラス「Piyota」を追加してみます。

//クラス「Piyota」
class Piyota {
    String name;

    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}


public class test01{
    public static void main(String[] args){

        System.out.println("Hello World");

    }
}


クラス「Piyota」には「name」というメンバ変数があります。
また「setName()」「getName()」というメソッドがあります。
メンバ変数」「メソッド」の意味が分からない方は、それぞれの用語の説明をご覧ください。
メソッドは「関数」と同じようなものと考えて構いません。用語の意味としては別のものですが、やってることは同じです。


さて、このクラス「Piyota」ですが、そのままでは使えません。
クラスは、あくまで設計図なのです。
この設計図を元にして、実際のもの(インスタンス)を作る作業が必要になります。

Javaの場合、設計図から実際のものを作る際には、例えば以下のように書きます。

Piyota p = new Piyota();

書き方ルールは

【設計図の名前】 【実際のものの名前】= new 【設計図の名前】()

です。
「=」の左側には

【設計図の名前】を元にして作ったものに【実際のものの名前】という名前を付けるから!

と書かれています。
「=」の右側には

【設計図の名前】を実際に作るから!

と書かれています。
プログラミングにおける「=」は「代入」の意味です。
右側のものを左側に入れるのです。

つまり、全体では

【設計図の名前】を実際に作って、それに【実際のものの名前】という名前を付けるから!

実際の名前に置き換えると

クラス「Piyota」を実際に作って、それに「p」という名前を付けるから!

と言っています。

このように、設計図を元にして実際のものを作ることを「newする」と言ったりします。
クラス(設計図)をnewしてインスタンス(実際のもの)を作っているからです。

話を戻します。
このnewする処理を先ほどのソースコードに追加してみましょう。

class Piyota {
    String name;

    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}

public class test01{
    public static void main(String[] args){
        //newする
        Piyota p = new Piyota();


        System.out.println("Hello World");

    }
}


そしてクラス「Piyota」の「name」の値を画面に表示してみます。

class Piyota {
    String name;

    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}

public class test01{
    public static void main(String[] args){
        Piyota p = new Piyota();

        //画面表示
        System.out.println(p.getName());


        System.out.println("Hello World");

    }
}


さて、このプログラムを実行するとどうなるでしょう?
実行結果は以下のようになります。

null
Hello World


null」は「何もないよー」の意味です。
クラス「Piyota」の「name」には何も値が設定されていません。

そうですね。
確かに「name」には何も入れていません。
何も入っていなくて当たり前です。

さぁ、長らくお待たせしました。
いよいよ、コンストラクタの登場です。

コンストラクタは「クラスをnewした瞬間に実行される関数」です。

あと、ついでなので書いておくと、Javaにおけるコンストラクタは

・クラス名と同じ名前にする必要がある
・戻り値(関数から戻す値)は返せない


というルールがあります。

それでは、先ほどのソースコードにクラス「Piyota」のコンストラクタを追加してみましょう。

class Piyota {
    String name;

    //コンストラクタ
    Piyota(){
    }


    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}

public class test01{
    public static void main(String[] args){
        Piyota p = new Piyota();

        System.out.println(p.getName());

        System.out.println("Hello World");

    }
}


ついでなので、コンストラクタの中で「name」に値「piyota」を設定しておきます。

class Piyota {
    String name;

    Piyota(){
        //値設定
        this.name = "piyota";

    }

    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}

public class test01{
    public static void main(String[] args){
        Piyota p = new Piyota();

        System.out.println(p.getName());

        System.out.println("Hello World");

    }
}


このプログラムを実行すると、以下のような結果になります。

piyota
Hello World


先ほど「null」だった「name」の値が「piyota」になりました。
これはコンストラクタ内で

this.name = "piyota";

を実行して、値を設定しているからです。

えっ?
本当にnewした瞬間に実行されているのか?ですか?

疑り深いですねー。

それでは、以下のようなソースコードではどうでしょうか。

class Piyota {
    String name;

    Piyota(){
        //メッセージ出力
        System.out.println("constructor");


        this.name = "piyota";
    }

    void setName(String _name){
        this.name = _name;
    }

    String getName(){
        return this.name;
    }
}

public class test01{
    public static void main(String[] args){
        //メッセージ出力
        System.out.println("before new");


        Piyota p = new Piyota();

        //メッセージ出力
        System.out.println("after new");


        System.out.println(p.getName());

        System.out.println("Hello World");

    }
}


このプログラムを実行すると、以下のような結果になります。

before new
constructor
after new
piyota
Hello World


如何でしょう。

before new
 ↓
constructor
 ↓
after new


の順番で表示されていますよね。
コンストラクタがnewした瞬間に動いていることが分かります。

このように、コンストラクタはクラスをnewした瞬間に実行される関数です。
最初にやっておかなくちゃいけない処理、例えばメンバ変数の初期化処理などでよく活用されます。

ただし、コンストラクタには、戻り値が返せなったりと制限もあります。
あまり複雑なことはやらせない方が良いでしょう。

さらに専門的な話になってしまいますが、Javaには「継承」という概念があります。
何も考えずにコンストラクタを定義してしまうと、親クラスのコンストラクタを上書きしてしまう場合があるのでご注意ください。

super();

とか書くと、親クラスのコンストラクタを呼び出せます。
親クラスのコンストラクタも生かしておきたい場合は、自分で定義したコンストラクタ内で呼び出してあげてください。

まぁ「コンストラクタ」って単語が出てきたら「クラスをnewした瞬間に実行される関数なんだな~」と思えばOKです。



■「コンストラクタ デストラクタ 違い」で情報をお探しの方へ

もしよろしければ、違いの分かるピヨピヨ「コンストラクタとデストラクタの違い」をご覧ください。