Developer

【はじめてのJava】同名の変数4【オブジェクトとクラス編】
2021.11.30
Lv1

【はじめてのJava】同名の変数4【オブジェクトとクラス編】

はじめてのJava

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


オブジェクトとクラス編

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

前回は「同名のインスタンス変数とローカル変数を呼び分ける方法」について扱いました。

今回は「同名のインスタンス変数とローカル変数を定義する必要性」について紹介します。


目次


変数のスコープ

 変数のスコープ とはその変数を利用可能な範囲のことです。

以前紹介したように「インスタンス変数」「static変数」「ローカル変数」では、変数のスコープが異なります。
では、もしも「インスタンス変数」「static変数」「ローカル変数」が同名だった場合はどうなるのでしょうか。

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


同名のインスタンス変数とローカル変数

前回説明した通り、インスタンス変数とローカル変数は同名で定義可能です。
同名で定義されている個所では、this.変数名ならインスタンス変数が、変数名だけならローカル変数が呼び出されます。

このように、仕掛けとしてはインスタンス変数とローカル変数を同名で定義することは可能です。しかし、インスタンス変数とローカル変数の名前を同名にするような書き方を多用すべきでしょうか。

筆者の主観ですが、「同名で定義することに利点があるかどうか」で分けるべきではないかと考えます。


同名で定義できる利点

では、同名で定義できる利点とは何でしょうか。

普通のメソッドでは、インスタンス変数と同名のローカル変数を定義すると、どちらの変数のことを指しているのか瞬別できず、戸惑ってしまいます。

しかし、setterと呼ばれるメソッドやコンストラクタの場合はインスタンス変数と引数(ローカル変数の1種です)を同名で定義する利点があります。

具体的に見てみましょう。


コンストラクタの引数名をインスタンス変数名に合わせる

一般に、コンストラクタの場合は、引数でインスタンス変数の初期値を指定します。

例えば、変数speed、color、companyを持ったCarクラスを考えてみましょう。

Carクラス

public class Car{
  double speed; //速度
  String color; //色
  String company; //メーカー
}

このCarクラスをインスタンス化する際に、それぞれの変数に初期値を与えるコンストラクタを考えます。例えば以下のようになります。

Carクラス

public class Car{
  double speed; //速度
  String color; //色
  String company; //メーカー

  Car(double s, String c1, String c2){
    this.speed = s; //speedの設定
    this.color = c1; //colorの設定
    this.company = c2; //companyの設定
  }
}

一見すると目立った問題はありません。しかし、このコードは本当に見やすいコードと言えるでしょうか。

一般に、他の人が書いたメソッドを利用する場合、引数名からどんな引数を渡せばよいのか見当を付けます。これはコンストラクタの際も同じです。今回のコンストラクタは引数が以下のようになっていました。

Car(double s, String c1, String c2)

書いた本人はこれでわかるかもしれません。しかし、他の人から見たら2つ問題点があります。

  1. 引数名を見ただけではどんな値を渡せばいいのか想像できない
  2. sは「speed」の頭文字だと推測できたとして、c1とc2はどっちが「color」でどっちが「company」か区別がつかない

この問題点は、インスタンス変数と同名の引数名を利用することで改善されます。
もし今回のコンストラクタの引数が以下のように書かれていたら、それぞれの引数がどのインスタンス変数を設定しているのか、一目瞭然です。

Carクラス

public class Car{
  double speed; //速度
  String color; //色
  String company; //メーカー

  Car(double speed, String color, String company){
    this.speed = speed; //speedの設定
    this.color = color; //colorの設定
    this.company = company; //companyの設定
  }
}

このような使い方は必須ではありません。しかし、コンストラクタやsetterの場合は、インスタンス変数と引数の変数名が一致していた方が、ソースコードの可読性が上がります。

ソースコード

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

public class Car{
  double speed; //速度
  String color; //色
  String company; //メーカー

  Car(double speed, String color, String company){
    this.speed = speed; //speedの設定
    this.color = color; //colorの設定
    this.company = company; //companyの設定
  }
}

まとめ

インスタンス変数とローカル変数は同名で定義可能
コンストラクタやsetterの引数名は、インスタンス変数と同名にしておいた方が可読性が高い

次回

次回は同名のstatic変数とローカル変数の扱いです。


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


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