Developer

【はじめてのJava】thisを使ったコンストラクタの呼び出し【オブジェクトとクラス編】
2021.08.31
Lv1

【はじめてのJava】thisを使ったコンストラクタの呼び出し【オブジェクトとクラス編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


オブジェクトとクラス編

オブジェクトとクラス編では、Javaを扱う上で非常によく出てくる「オブジェクト」や「クラス」について扱っていきます。

前回は「イニシャライザ」について扱いました。

今回は「thisを使って別のコンストラクタを呼び出す方法」について扱います。


目次


thisを使った別のコンストラクタの呼び出し

 

コンストラクタが複数定義されていたとしてもインスタンス化の際には 1つしか動作しません 
ですが、別のコンストラクタを呼び出したい場合も考えられます。

そのような場合、thisキーワードを用いることで別のコンストラクタを呼び出すことが可能です。

次の図のようなイメージです。

詳しく見ていきましょう。


thisとは

 this とはオブジェクトが自分自身のことを指す際に使うキーワードです。

例えば、Aさん(20歳)とBさん(30歳)という2人の人がいたとします。この時2人が同じ「私の年齢は…」という言葉を発した場合でも、Aさんは「20歳」ですがBさんにとっては「30歳」となります。
thisが指し示すのはこの「私」に相当する意味合いです。

いままでコンストラクタ内で「this.speed = 0;」「this.color = “red”;」などと書いていました。この場合のthisも自分自身といった意味合いでとらえることが可能です。
thisがついている変数は「インスタンス変数の」と読み替えることができます。ですのでそれぞれ「私自身の(インスタンス変数の)speedを0にする」「私自身の(インスタンス変数の)colorをredにする」といった意味合いでとらえることができます。

このthisを使うと、 インスタンス化の際に別のコンストラクタを呼び出すことが可能 になります。

具体的に見ていきましょう。

thisを使った別のコンストラクタの呼び出し方

では、thisを使ったコンストラクタの呼び出し方を見てみましょう。
thisを使った別のコンストラクタの呼び出し方の書式は次の通りです。

thisを使った別のコンストラクタの呼び出し方

this(/*呼び出すコンストラクタに渡す引数*/);

コンストラクタを合わせて記載すると次のようになります。

class Sample{
 
  //引数のないコンストラクタ
  Sample(){
    this("red"); //引数のデータ型が一致している★のコンストラクタを呼びなおしている
    //★呼び出し後の処理
  }
   
  //↓引数付きのコンストラクタ
  Sample(String color){ //★
    //★で実行する処理
  }    
}

Carクラスを例に見てみましょう。
thisを使ってコンストラクタを呼びなおすようにしたCarクラスは以下の図のようなイメージです。

引数無しのコンストラクタでインスタンス化を行った場合、”red”という引数で引数ありのコンストラクタを呼び出しなおします。

実際にこのCarクラスを例にソースコードを書いてみると次のようになります。

class Car{
  double speed;
  String color;
 
  //引数のないコンストラクタ
  Car(){
    this("red"); //下のコンストラクタ★を呼びなおしている
  }
   
  //↓引数付きのコンストラクタ
  Car(String color){ //★
    this.speed = 0;
    this.color = color;
  }    
}

このようにして「コンストラクタから別のコンストラクタを呼び出す」ことができます。

ただし、コンストラクタの呼び出し直しをする際には注意点があります。


コンストラクタの呼び出し直しの注意点

コンストラクタから別のコンストラクタを呼び出す際には 別のコンストラクタの呼び出しは真っ先に行う 必要があります。

例えば、次のようなに 別のコンストラクタを呼び出す前にほかの処理を実行しているとコンパイルエラーです 

コンパイルエラーになる例(BadCar.java)

class BadCar{
  double speed;
  String color;
  
  //引数のないコンストラクタ
  BadCar(){
    System.out.println(); //コンストラクタの呼びなおしより先に処理を書いてはダメ
    this("red"); //コンパイルエラー
  }
    
  //↓引数付きのコンストラクタ
  BadCar(String color){
    this.speed = 0;
    this.color = color;
  }    
}

これはJava Silverの資格試験では頻出です。試験の受験を考えている場合は必ず理解しておいてください。


【コラム】;(セミコロン)の扱い

Javaでは処理の終端に;(セミコロン)を付けます。これは、「セミコロンまでで1つの処理ですよ」ということを明示しているためだと思われます。

では、;(セミコロン)しかない場合はどういった扱いになるのでしょうか

実は;(セミコロン)1文字だけでも処理とみなされます。処理内容がない処理、という、なんだかややこしい処理になっていますが、1つの処理であることには変わりません。

そのため、次の例はコンパイルエラーになります。

コンパイルエラーになる例(BadCar.java)

class BadCar{
  double speed;
  String color;
  
  //引数のないコンストラクタ
  BadCar(){
    ; //処理内容は無いが、コンストラクタの呼びなおしよりも前に処理が書かれていることになる
    this("red"); //↑のセミコロンが原因でコンパイルエラー
  }
    
  //↓引数付きのコンストラクタ
  BadCar(String color){
    this.speed = 0;
    this.color = color;
  }    
}

ソースコード

今回使用したソースコードをまとめて記載します。

Carクラス

class Car{
  double speed;
  String color;
  
  //引数のないコンストラクタ
  Car(){
    this("red"); //下のコンストラクタ★を呼びなおしている
  }
    
  //↓引数付きのコンストラクタ
  Car(String color){ //★
    this.speed = 0;
    this.color = color;
  }    
}

まとめ

thisキーワードはオブジェクトが自分自身を表す際に使われる
thisを使うとコンストラクタ内で別のコンストラクタを呼びなおすことが可能
コンストラクタの呼びなおしは必ずコンストラクタ内の先頭に書かなければならない


次回

次回も引き続きクラスやオブジェクトに関する内容を扱います。


はじめてのJavaシリーズの目次はこちら
オブジェクトとクラス編はこちら


java 11 の練習問題一覧はこちら
はじめてのJavaシリーズの練習問題一覧はこちら