Help us understand the problem. What is going on with this article?

【初心者向け】javaのコンストラクタについてまとめ

More than 1 year has passed since last update.
コンストラクタとは

コンストラクタとは、newで生み出されたインスタンスに自動で情報(フィールド)を渡してくれるものです。

public class Hero {
    String name;
    int hp;
}

このHeroクラスをインスタンス化すると、値の入っていないHero(nameがnullでhpが0)が生成されてしまいますが

public class Hero {
    String name;
    int hp;

    //コンストラクタ
    Hero(){
        this.name = "名前";
        this.hp = 100;
    }
}

こうすることによって値をフィールドに代入できます。
でもこれだと同じ名前と同じHPのHeroしか作ることができません。
魔法使いHP50とか、妖精HP70とかが作れないのです。
なので、自由にキャラクターを作れるようにするためにこのようにします。

public class Hero {
        String name;
        int hp;

        //コンストラクタ
        Hero(String name , int hp){
            this.name = name;
            this.hp = hp;
        }
}

これは何をしているかというと、Hero(String name , int hp)でnameとhpを受け取って、フィールドに代入しているのです。
どこから受け取っているのかというと、mainメソッドから受け取っています。

public static void main(String[] args) {
        Hero h = new Hero("勇者" , 100);
    }

Heroクラスで引数を2つ受け取るコンストラクタを設定したので、呼び出すときも引数を2つ設定して呼び出します。
これが引数1つだとエラーになります。

結果はこうなります。
ちゃんと値が渡されているか確認しましょう。

public static void main(String[] args) {
        Hero h = new Hero("勇者" , 100);
        System.out.println("名前は" + h.name + "です。");
        System.out.println("HPは" + h.hp + "です。");
    }

結果は

名前は勇者です
HPは100です

ちゃんと渡すことができました。

でもこれだと、名前だけを渡したい場合エラーになってしまいます。

public class Main {

    public static void main(String[] args) {
        Hero h = new Hero("勇者");//エラーになる
    }
}

こんな時はHeroメソッドにコンストラクタを追加します。

public class Hero {
        String name;
        int hp;

        //コンストラクタ
        Hero(String name , int hp){   //ひとつ目のコンストラクタ
            this.name = name;
            this.hp = hp;
        }
        Hero(String name){   //ふたつ目のコンストラクタ
            this.name = name;   
            this.hp = 50;
        }
}

コンストラクタは、名前が同じでも、引数の数が違えば複数設定できるのです。
これをオーバーロードと言います。
もしmainメソッドでnewして呼び出すとき、引数にnameとhpがあったらひとつ目のコンストラクタが呼び出されます。
引数にnameだけがあったらふたつ目のコンストラクタが呼び出されます。
このままでもエラーにはなりませんが、渡されるフィールドが増えてきたりすると、修正や可読性が悪くなってしまいます。
なので

this()

を使います。
これを使うと、同じメソッドにあるコンストラクタを呼び出すことができます。

public class Hero {
        String name;
        int hp;

        //コンストラクタ
        Hero(String name , int hp){   //ひとつ目のコンストラクタ
            this.name = name;
            this.hp = hp;
        }
        Hero(String name){   //ふたつ目のコンストラクタ
            this(name , 50);
        }
}

こうなります。
ふたつ目のコンストラクタの中でひとつ目のコンストラクタを呼び出しているのです。
ひとつ目のコンストラクタは引数が2つあるのでthis()の()の中の引数は2つです。
nameはmainメソッドから渡されたものが入り、hpは渡されないので任意のhpを入れます。ここでは50としています。
これで実行すると

public class Main {

    public static void main(String[] args) {
        Hero h = new Hero("勇者");
        System.out.println("名前は" + h.name + "です。");
        System.out.println("HPは" + h.hp + "です。");
    }
}

結果

名前は勇者です
HPは50です

ちゃんと50が渡されてますね。
this()は結構ややこしいですね。ひとつずつ書いたほうが分かりやすいよ!と思ってる方もいると思いますが、そうすると後からフィールドを変更しなければならなくなった時大変になります。

public class Hero {
        String name;
        int hp;

        //コンストラクタ
        Hero(String name , int hp){   //ひとつ目のコンストラクタ
            this.name = name;
            this.hp = hp;
        }
        Hero(String name){   //ふたつ目のコンストラクタ
            this.name = name;   
            this.hp = 50;
        }
}

こんなふうに書いていて、あとからフィールドを変更しなければならなくなると

public class Hero {
        String name1;  //ここをname1に変更しなければならない。
        int hp;

        //コンストラクタ
        Hero(String name , int hp){   //ひとつ目のコンストラクタ
            this.name = name;  //エラーになる。
            this.hp = hp;
        }
        Hero(String name){   //ふたつ目のコンストラクタ
            this.name = name;  //エラーになる。
            this.hp = 50;
        }
}

この場合2か所直さないといけなくなります。
コンストラクタが2つならまだいいですが、これが増えてくると作業が大変になります。
なん十か所も直していたら一か所くらいミスが出てもおかしくありません。

自分がつまずいた部分だったのでまとめてみました。
間違いがありましたら指摘をお願いします。

nkojimaさんご指摘ありがとうございます。
記事の一部を削除しました。
確かに読み返してみたら可読性とは違いましたね。
送っていただいた記事も参考にさせていただきます。

hrs_myk
33歳IT業界未経験がWEBエンジニアを目指します! 現在約3カ月のスクールを終え、java/html/mysqlの基本を学び就職に向け奮闘中。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした