未来エンジニア養成所Blog

月単価180万以上のプログラミング講師がプログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】オブジェクト指向の基本問題2-1

title


問題2-1

従業員を表すEmployeeクラスを作成してください。

Employeeクラスを利用するClassFirstPracticeクラスのmainメソッドはすでに完成しています。
(変更は禁止です)


【Employeeクラス】
Employeeクラスはフィールドとして社員番号(int型)と社員名(String型)の2つの情報を保持します。

Employeeクラスには次の3つのメソッドが必要です。

  1. 社員番号と社員名をオブジェクトにセットするためのsetDataメソッド
  2. 社員番号の情報をオブジェクトから取得するためのgetIdメソッド
  3. 社員名の情報をオブジェクトから取得するためのgetNameメソッド


【実行結果】

社員番号:1234
社員名:山田


【ClassFirstPractice.java】

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

        // Employeeクラスのオブジェクトを作成
        Employee employee = new Employee();

        // Employeeオブジェクトに社員番号と社員名をセット
        employee.setData(1234, "山田");

        // Employeeオブジェクトの社員番号を出力
        System.out.println("社員番号:" + employee.getId());

        // Employeeオブジェクトの社員名を出力
        System.out.println("社員名:" + employee.getName());


    }
}


// ここにEmployeeクラスを作成してください。


解答例

【ClassFirstPractice.java】

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

        // Employeeクラスのオブジェクトを作成
        Employee employee = new Employee();

        // Employeeオブジェクトに社員番号と社員名をセット
        employee.setData(1234, "山田");

        // Employeeオブジェクトの社員番号を出力
        System.out.println("社員番号:" + employee.getId());

        // Employeeオブジェクトの社員名を出力
        System.out.println("社員名:" + employee.getName());


    }
}

// Employeeクラス
class Employee {
    // 社員番号
    private int id;

    // 社員名
    private String name;

    // 社員番号と社員名をオブジェクトにセットする
    public void setData(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // 社員番号の情報を取得する
    public int getId() {
        return id;
    }

    // 社員名の情報を取得する
    public String getName() {
        return name;
    }
}


解説

今回作成するクラスのメンバには、2つのインスタンスフィールドと、3つのインスタンスメソッドがあります。

一般的には先にインスタンスフィールドの定義を記述します。


インスタンスフィールドの定義を次のように記述していませんか?

class Employee {
    // 社員番号
    int shainBangou;

    // 社員名
    String shainMei;

    .....
}



このプログラムには、良くないポイントが2つあります。


まず1つ目は、アクセス修飾子が付加されていないことです。

Javaのアクセス修飾子には、厳しい方から「private」「何も書かない(デフォルトと呼ばれます)」「protected」「public」の4種類あります。

Javaのクラス作成の基本としては、カプセル化とデータ隠蔽の考え方に従い、インスタンスフィールドはprivateアクセス、つまりアクセス権限を一番厳しくして外部から直接アクセスできないようにするのが基本です。
(状況によってはprotectedにします)


直接は他のクラスからデータにアクセスできなくなるため不便に感じるかもしれません。


しかし、そのためにデータを設定するためのメソッド(セッターメソッドと言います)と、データを取得するためのメソッド(ゲッターメソッドと言います)をpublicアクセスにして、これらのメソッド(アクセサメソッドと言います)を経由してデータ操作を行うのがクラス作成の基本中の基本となります。



次に良くない点の2つ目ですが、フィールド名がローマ字になっています。

これはダメです。


ただし、こんな意見もあるかもしれません。

「今回の問題の指示では、フィールド名の指定はなかった!だったらどんなフィールド名でも良いでしょ!」


確かに問題文にはフィールド名の指示はありませんでした。

しかし、実はその答えは既に書いてあるようなものなのです。



社員番号を取得するメソッドはgetId、社員名を取得するメソッドはgetNameという指示があります。

このインスタンスフィールドの情報を取得するための小文字getで始まるメソッドはゲッターメソッドと呼ばれますが、その場合はインスタンスフィールド名の頭にgetを付けて、インスタンスフィールド名の先頭を大文字に変えてあげるのが一般的なルールです。
(ちなみにboolean型インスタンスフィールドの場合はgetの代わりにisが良く使われます)



よって、getIdメソッドで取得する情報をidインスタンスフィールドの情報、getNameメソッドで取得する情報はnameインスタンスフィールドの情報であるのがJavaのマナーなのです。


どのプログラミング言語でもそうですが、その言語に特化したマナーが必ず存在しますので、それに従うようにしましょう。



あとはインスタンスメソッドsetDataなのですが、次のように記述された人もいるかもしれません。

// 社員番号と社員名をオブジェクトにセットする
public void setData(int i, String s) {
    id = i;
    name = s;
}


メソッドの引数名が「int i, String s」というのは、イマイチです。

変数や引数などの識別子は、名前だけでその意味がわかるように命名するのが鉄則です。
(インクリメント変数i、j、kや、例外オブジェクトeなどは例外)



今回、setDataメソッドの2つの引数は、2つのインスタンスフィールドに値を渡すためのものですから、インスタンスフィールド名と同じ名前にするのが一般的です。

その場合は、インスタンスフィールドの方にthisキーワードを付加します。


「thisキーワードって分かりにくくて嫌いなんですよ」


こんな声も良く聞かれます。

しかし、それほど難しいものではないです。

英語の「this」は、「この」という意味です。

それを「このインスタンス自身の」、あるいは「私の」と読み替えてあげれば良いのです。


つまり、「this.id」「このインスタンス自身のid」、つまり「インスタンスフィールドのid」と考えれば良いのです。


// 社員番号と社員名をオブジェクトにセットする
public void setData(int id, String name) {
    this.id = id;
    this.name = name;
}


この引数で受け取った値をフィールドにセットする「this.id = id;」の形は、Javaではお決まりのパターンなので自然に記述できるようにしましょう。



なお、今回は初歩の問題としましたので、まだコンストラクタは出てきませんでしたが、本当はsetDataメソッドよりもコンストラクタを使うほうが自然だと言えます。


参考図書



LINE公式アカウント

仕事が辛くてたまらない人生が、仕事が楽しくてたまらない人生に変わります。
【登録いただいた人全員に、無料キャリア相談プレゼント中!】


LineOfficial

友だち追加



【まついのLINE公式アカウントはこちらから!】
Line公式アカウント