Javaのオブジェクト指向備忘録(1)

間違えがあればコメントから教えてもらえると有難い。

@Contents

オブジェクト指向の概要

  • オブジェクト指向の特徴
    • 属性情報を持っている(プロパティ
      • プロパティやメンバ、フィールドなどの変数
    • 振る舞いを持っている(メソッド
    • ひとつひとつのオブジェクトは唯一無二の存在である
      • クラスという金型を用いて、個体としては異なるオブジェクトを生成する
    • オブジェクトとオブジェクトに関係性を持たせられる

※オブジェクト(参照型)が持つデータなのでプロパティも参照型のデータにする(プリミティブ型でも問題はない)。

  • パッケージ=PCのフォルダのようなもの
    • カテゴリ分けなどをして小分けにしてまとめる
  • 自分で開発する場合は、機能やカテゴリに応じてパッケージを切って命名
  • パッケージ名にはjavaは使用できない
  • オブジェクト指向を使うことでクラスファイルを大量に作成する手間が省ける
    • パッケージを使用すれば
package test;

public class Student {

    // プロパティ
    public String studentName; // 生徒名
    public String clubName; // 部活動

    // 自己紹介メソッド
    public void introduce() {
        System.out.println("My name is " + studentName + ".");
        System.out.println("I belong to the " + clubName + ".");
    }
}
  • packageの後にパッケージ名を書けば、ひとまとまりのパッケージとして扱うことが可能
  • public:修飾子の一つ
    • 複数のファイルに分かれる場合は「どのオブジェクトが操作可能か」指定する必要がある
    • publicはどのオブジェクトも操作できることを指定する修飾子
  • 上記のコードは単体では実行できない(メインメソッドがないので)
    • 他から呼び出して利用するクラスである

インスタンスの作成

package test;

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

        Student stu = new Student();

        stu.studentName = "Kiki";
        stu.clubName = "PC club";

        stu.introduce();
    }
}
My name is Kiki.
I belong to the PC club.
  • Student stu = new Student();で初期化
    • Studentクラスの変数stuに対し、右辺のnewによりインスタンスを作成して代入している
      • インスタンス=実物のオブジェクト
      • 上記を実行することでStudentクラスが1つのインスタンスとして実体化し、変数stu に格納される
        • stuが実在のものになる
  • stu.studentName = "Kiki";stu.clubName = "PC club";
    • インスタンス化しただけではStudentクラスのプロパティの生徒名と部活動名には何も入っていない状態
    • なので<インスタンスが格納された変数名>.<プロパティ名> という記述で値をセット
      • . は、助詞の「の」みたいなもの
  • stu.introduce();
    • Studentが持っている introduceメソッドを実行
    • <インスタンスが格納された変数名>.<メソッド名>(<引数(必要であれば)>)
      • 特定のクラスが持っているメソッドを実行可能

例:さらにStudentにプロパティとメソッドを追加↓

package test;

public class Student {
    // プロパティ
    public String studentName; // 生徒名
    public String clubName; // 部活動
    public int vitality; // 体力

    // 自己紹介メソッド
    public void introduce() {
        vitality -= 10;
        System.out.println("My name is " + studentName + ".");
        System.out.println("I belong to the " + clubName + ".");
    }

    // 挨拶をするメソッド
    public void greeting() {
        vitality -= 10;
        System.out.println("Good morning!");
    }

    // 報告するメソッド
    public void report() {
        vitality -= 10;
        System.out.println("I studied for 2 hours this morning.");
    }

    // 残り体力を知らせるメソッド
    public void showVitality() {
        vitality -= 10;
        System.out.println("I have " + vitality + " health points left.");
    }

    // 登校するメソッド
    public void goToSchool() {
    }

    // 下校するメソッド
    public void leaveSchool() {
    }
  • プロパティに体力を追加
  • 登校と下校は未実装
  • 何か行動(この場合はメソッドを実行)すると、体力を10消費する
package test;

public class ObjectSample {
    public static void main(String[] args) {
        
        Student stu01 = new Student();

        stu01.studentName = "Kiki";
        stu01.clubName = "PC club";
        stu01.vitality = 150;

        stu01.introduce();
        stu01.showVitality();
    }
}
My name is Kiki.
I belong to the PC club.
I have 130 health points left.
  • データの項目はプロパティにもたせる
    • そのクラスで行いたい機能をメソッドとして実装

例:2人目のインスタンスを追加↓

package test;

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

        Student stu02 = new Student();

        stu02.greeting();   
     
        stu02.studentName = "Keiten";
        stu02.clubName = "English club";
        stu02.vitality = 250;

        stu02.introduce();
        stu02.report();
        stu02.showVitality();
    }
}
Good morning
My name is Keiten.
I belong to the English club.
I studied for 2 hours this morning.
I have 210 health points left.
  • 別々のインスタンス
    • それぞれが値を持っており、お互いに干渉しない
  • Studentクラスに基づいて大量生産ができる

プロパティの初期値

例:設定する前に参照↓

package test;

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

        Student stu01 = new Student();

        //stu01.studentName = "Kiki";
        //stu01.clubName = "PC club";
        //stu01.vitality = 150;

        stu01.introduce();
        stu01.showVitality();
    }
}
My name is null.
I belong to the null.
I have -20 health points left.
  • null=参照なし
  • インスタンスとしてstu01は存在している
    • しかし、中身に値を代入しない限りはnullになる
    • 中身:String studentNameString clubName
  • intの場合は基本データ型なので0が入る

例:ということなので、プロパティに初期値を設定↓

package test;

public class Student {
    // プロパティ
    public String studentName = "secret"; // 生徒名
    public String clubName = "homecoming club"; //部活動
    public int vitality = 0; // 体力
}
私の名前は秘密です。
部活動は帰宅部です。
残り体力は-20
My name is secret.
I belong to the homecoming club.

相互に依存しない独立した仕組みを作ることで、プログラムの維持管理や修正が容易になる。

コンストラクタを設定

  • コンストラクタ=プロパティの初期値を設定するもうひとつの方法
    • クラスを初期化する時の処理をこちらで決めることが可能
    • インスタンスをnewした時に呼び出される
    • 呼び出さないというのはJavaの仕組み上不可能
    • メソッドではなく、特殊な扱いである

例:コンストラクタを利用↓(前述の初期値は復元)

package test;

public class Student {
    // プロパティ
    public String studentName; // 生徒名
    public String clubName; //部活動
    public int vitality; // 体力

    // コンストラクタ
    public Student() {
        System.out.println("The constructor was called during initialization.");
        studentName = "secret";
        clubName = "homecoming club";
        vitality = 0;
    }

    // 自己紹介メソッド
    public void introduce() {
        vitality -= 10;
        System.out.println("My name is " + studentName + ".");
        System.out.println("I belong to the" + clubName + ".");
    }

    // 挨拶をするメソッド
    public void greeting() {
        vitality -= 10;
        System.out.println("Good morning.");
    }

    // 報告するメソッド
    public void report() {
        vitality -= 10;
        System.out.println("I studied for 2 hours this morning.");
    }

    // 残り体力を知らせるメソッド
    public void showVitality() {
        vitality -= 10;
        System.out.println("I have " + vitality + " health points left.");
    }

    // 登校するメソッド
    public void goToSchool() {
    }

    // 下校するメソッド
    public void leaveSchool() {
    }
}
The constructor was called during initialization.
My name is secret.
I belong to the homecoming club.
I have -20 health points left.
  • クラス名()がコンストラクタの文法ルール
    • メソッドと似ている
    • クラス名と完全一致しないと単なるメソッドになるので注意
  • 書く順番は、プロパティ -> コンストラクタ -> メソッド
    • 暗黙の了解
  1. 通常、プロパティは型と変数名だけの定義でデータは持たせない
  2. インスタンス化した時に(実体化)データを設定 / 代入する
    • なぜなら、インスタンス化した時にクラスに書いてあるコンストラクタの処理が行われるから
    • 例:Student stu01 = new Student();の実行時に//コンストラクタ内の処理
  3. 初期化した時点で、Studentクラスのコンストラクタが呼ばれる
    • stu01には名前がsecret、部署名にhomecoming clubというデータが入った状態に
  4. introduceメソッドを実行した時に、stu01の初期値の2つがしっかりと表示される

例:引数つきのコンストラクタもあるので設定↓

package test;

public class Student {
    // プロパティ
    public String studentName; // 生徒名
    public String clubName; //部活動
    public int vitality; // 体力

    // コンストラクタ
    public Student() {
        System.out.println("The constructor was called during initialization.");
        studentName = "secret";
        clubName = "homecoming club";
        vitality = 0;
    }

    // 引数ありコンストラクタ
    public Student(String studentName, String clubName, int vitality) {
        System.out.println("The constructor with arguments was called during initialization.");
        this.studentName = studentName;
        this.clubName = clubName;
        this.vitality = vitality;
    }

    // 自己紹介メソッド
    public void introduce() {
        vitality -= 10;
        System.out.println("My name is " + studentName + ".");
        System.out.println("I belong to the" + clubName + ".");
    }

    // 挨拶をするメソッド
    public void greeting() {
        vitality -= 10;
        System.out.println("Good morning.");
    }

    // 報告するメソッド
    public void report() {
        vitality -= 10;
        System.out.println("I studied for 2 hours this morning.");
    }

    // 残り体力を知らせるメソッド
    public void showVitality() {
        vitality -= 10;
        System.out.println("I have " + vitality + " health points left.");
    }

    // 登校するメソッド
    public void goToSchool() {
    }

    // 下校するメソッド
    public void leaveSchool() {
    }
}
The constructor was called during initialization.
My name is secret.
I belong to the homecoming club.
I have -20 health points left.
The constructor with arguments was called during initialization.
My name is Keiten.
I belong to the English club.
Good morning.
  • this:プロパティの方のstudentNameを明示して指定
    • プロパティと引数の見分けがつくように
    • 何もない方が引数の方のstudentName
  • プロパティと引数の名前は揃えなければならない
    • プロパティの変数名と同じ=どこに何の値が入ったか明確
  • コンストラクタはいくつでも作成可能
  • コンストラクタを書かなくても、デフォルトコンストラクタがJavaの実行時には自動的に作成、実行されている
    • 引数もなく中身は何もなく何も実行しないコンストラクタ
      • これによりコンストラクタを省略しても、Studentクラスの初期化が行えた

例:引数なしコンストラクタを削除して警告を出す↓

package test;

public class Student {
    // プロパティ
    public String studentName; // 生徒名
    public String clubName; //部活動
    public int vitality; // 体力

    // コンストラクタ
    /*
    public Student() {
        System.out.println("The constructor was called during initialization.");
        studentName = "secret";
        clubName = "homecoming club";
        vitality = 0;
    }
    */

    // 引数ありコンストラクタ
    public Student(String studentName, String clubName, int vitality) {
        System.out.println("The constructor with arguments was called during initialization.");
        this.studentName = studentName;
        this.clubName = clubName;
        this.vitality = vitality;
    }

    // 自己紹介メソッド
    public void introduce() {
        vitality -= 10;
        System.out.println("My name is " + studentName + ".");
        System.out.println("I belong to the" + clubName + ".");
    }

    // 挨拶をするメソッド
    public void greeting() {
        vitality -= 10;
        System.out.println("Good morning.");
    }

    // 報告するメソッド
    public void report() {
        vitality -= 10;
        System.out.println("I studied for 2 hours this morning.");
    }

    // 残り体力を知らせるメソッド
    public void showVitality() {
        vitality -= 10;
        System.out.println("I have " + vitality + " health points left.");
    }

    // 登校するメソッド
    public void goToSchool() {
    }

    // 下校するメソッド
    public void leaveSchool() {
    }
}
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	コンストラクター Student() は未定義です

	at test.ObjectSample.main(ObjectSample.java:7)
  • Student stu01 = new Student();にエラーが発生
    • デフォルトコンストラクタ(空のコンストラクタ)が消えているから
      • 1つでも自分でコンストラクタを定義すると消えてしまう
  • この場合は引数なしのコンストラクタを定義するとコンパイルエラーは消える
    • 例:public Student() {}(デフォルトコンストラクタ)
  • 引数ありのコンストラクタを定義した場合は引数なしも記述しておくと安全

To comment

@Contents
閉じる