KATOエンジニヤリング開発日誌

「アウトプット無きエンジニアにインプットもチャンスも無い」の精神で書いています

Javaのオーバーロードとコンストラクタについて学ぶ

「Javaプログラミング技法」の第5回目の授業まとめになります。

※前回授業の内容はこちら

www.kato-eng.info

クラスメンバへのアクセス制限

クラスメンバへのアクセス制限が無い場合、別のクラスからフィールドに直接アクセスできてしまい、クラスを作成したプログラマが想定していない値を設定されてしまうことがありえる。

// Ninja.java ファイル

package basic;

public class Ninja {
    int hitPoint;

    void setHitPoint(int hitPoint) {
        this.hitPoint = hitPoint;
        return;
    }

    int getHitPoint() {
        return this.hitPoint;
    }
}

Ninjaクラスのフィールドである「id」を別クラスから操作する。

// NinjaManager.java ファイル

package basic;

public class NinjaManager {

    public static void main(String[] args) {
        Ninja sasuke = new Ninja();

        sasuke.hitPoint = 500; // NinjaクラスフィールドのhitPointに直接数値を入れる
        System.out.println(sasuke.hitPoint);
    }
}

出力結果は下記の通り。

500

Ninjaクラスのフィールド「hitPoint」に値を入れる「setHitPoint」メソッドを使わずにフィールド変数に値を代入できてしまった。

別クラスからフィールドへの直接アクセスを禁止する対策が必要になる。

// Ninja.java ファイル

package basic;

public class Ninja {
    private int hitPoint; // フィールド変数に「private」修飾子をつける

    // 他クラスから呼び出したいメンバには「public」修飾子をつける
    public void setHitPoint(int hitPoint) { 
        this.hitPoint = hitPoint;
        return;
    }

    public int getHitPoint() {
        return this.hitPoint;
    }
}
// NinjaManager.java ファイル

package basic;

public class NinjaManager {

    public static void main(String[] args) {
        Ninja sasuke = new Ninja();

        //sasuke.hitPoint = 500; // コメントアウトを外すとここでコンパイルエラーが発生してしまう
        //System.out.println(sasuke.hitPoint);

        sasuke.setHitPoint(500);
        System.out.println(sasuke.getHitPoint());
    }
}
  • クラスメンバを宣言するときに修飾子をつけることでアクセス制限ができる
  • privateなメソッドにpublicなメソッドを用いてアクセスできるようにすることをカプセル化と呼ぶ

メソッドのオーバーロード

1つのクラスの中に同じ名前を持つメソッドを複数つくることをオーバーロードと呼ぶ。オーバーロードを実現するためには、メソッドの名前を同じにした場合に「引数の型」「引数の個数」「並び順」のどれかが異なっている必要がある。

class Student {
    private int id;
    private double score;

    public void setStudent(int id) {
        this.id = id;
    }

    public void setStudent(double scr) {
        this.score = scr;
    }

    public void setStudent(int id, double scr) {
        this.id = id;
        this.score = scr;
    }

    /* 引数の型・個数・並び順が1つめのsetStudentと被るのでエラーになる
    public void setStudent(int i) {
        this.id = i;
    }
    */
}

コンストラクタ

  • コンストラクタとはインスタンスを生成したときに実行される処理を定義したものである
  • コンストラクタの名前はクラス名と同じ名前にしてあげる必要がある
  • メソッドとは異なりコンストラクタには戻り値の型を指定しない
  • コンストラクタもオーバーロードできる
// Student.java ファイル

class Student {
    private int id;
    private double score;

    // 引数無しでStudentクラスを生成した際のコンストラクタ
    public Student() {
        this.id = 123;
        this.score = 50.0;
    }

    // int型、double型の順で引数を指定したStudentクラスを生成した際のコンストラクタ
    public Student(int id, double score) {
        this.id = id;
        this.score = score;
    }

    // 以下略
}
// StudentManager.java ファイル

class StudentManager {
    public static void main(String[] args) {
        // 引数無しでStudentクラスを生成する
        Student student1 = new Student()
        
        // int型、double型の順で引数を指定してStudentクラスを生成する
        Student student2 = new Student(130, 65.0);

        /*
        student1のインスタンスはid = 123, score = 50.0で初期化されている
        student2のインスタンスはid = 130, score = 65.0で初期化されている
        */        
    }
}

コンストラクタには重要な注意点がある。今まではコンストラクタを指定していなかったが、コンストラクタが実行されていなかったわけではなく、javaが自動で引数無しのコンストラクタを用意していた。これをデフォルトコンストラクタと呼ぶ。しかし、クラスにコンストラクタを1つでも用意するとデフォルトコンストラクタは無効になる。

// Student.java ファイル

class Student {
    private int id;
    private double score;

    // int型、double型の順で引数を指定したStudentクラスを生成した際のコンストラクタ
    // 引数無しのコンストラクタは作成していない
    public Student(int id, double score) {
        this.id = id;
        this.score = score;
    }

    // 以下略
}
// StudentManager.java ファイル

class StudentManager {
    public static void main(String[] args) {
        // 引数無しでStudentクラスを生成する
        Student student1 = new Student()
        
        /*
        Studentクラスでデフォルトコンストラクタが作成されず、
        引数無しのコンストラクタを作成していないのでコンパイルエラーになる
        */
    }
}

※次回の授業内容はこちら

www.kato-eng.info