カプセル化、list、Java

カプセル化

クラス     →   インスタンス化(オブジェクト)
:フィールド
:メソッド
→コンストラクタ(newインスタンス化されるタイミングで実行されるメソッド)
 通常メソッド
 ゲッターセッター

カプセル化とは

オブジェクト内のクラスやメソッド、フィールドに対して外部からアクセスを制限する仕組みのことで
フィールドはprivateにしてそれぞれのフィールドに対してgetter,setterをつくることでカプセル化という概念を実現できます。
privateで定義されたフィールドとgetter,setterが存在する。カプセル化の仕組みを実現した入れ物をbeanというオブジェクトで呼ぶ。
これをすることでUserクラスのオブジェクトは外部から勝手に改変できない またはオブジェクトがもつデータをオブジェクト内でチェックできるのでオブジェクトの信頼性が高まる

Mainクラス

public class Mainexe {
    /**
    * 今回はUserのリストを作って回す
    * ①コンストラクタ(newをするタイミングで処理を行う)
    * ②Userのリストを回す→①②ができたらメインクラスとuserクラスの役割がわかれる
    * ③アクセス修飾子(private,public)とBean,カプセル化を理解する
    * @param args
    */
    public static void main(String[] args) {


        User user1 = new User("meo1", 5000);      
        User user2 = new User("meo2", 2);
        User user3 = new User("meo3", 65);

//カプセル化の概念に乗っ取るとフィールドは直接書き換えれないのでこのように書いてはいけない
        //user1.amount = 1000000;
        user1.setAmount(11);
        user2.setAmount(-11);

        String aaa = user1.getUserName();
        

        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        
        for(User tarUser : userList) {
            tarUser.rankJudge();
            tarUser.output();
        }
    }
}

引数有りコンストラク
User user1 = new User("meo1", 5000);
MainクラスはUserクラスに対してnewをお願いします。必要な値として(meo1,5000)を渡しました。
new Userの中にはいるとid=〇〇で管理されたuserオブジェクト視点にうつりmain側の引数からパラメータに値をもってきてる
Userクラスのコンストラクタが実行され、id=〇〇で管理されたuserオブジェクトのフィールドuserNameにinputNameがはいる
amountはコンストラクタのchkAmountの中のchkAmountメソッドで0以上ならtureそれ以外ならfalseが返され、コンストラクタのchkAmountメソッドで今回は5000なのでそのまま値がはいる。0以下なら0が入る。

Userクラスのコンストラク

戻り値がbooleanのchkAmountメソッドはコンストラクタのchkAmountとセッターのchkAmountをさらにメソッド化している

//コンストラクタ
public User (String inputName, int inputAmount) {
        this.userName = inputName;
        if (this.chkAmount(inputAmount)) {
            this.amount = inputAmount; 
        }else {
            this.amount = 0;
        }
    }
///chkAmountメソッド
private Boolean chkAmount (int chkAmoumt) {
        if(chkAmoumt > 0) {
            return true;
        }else{
            return false;
        }
    }
//セッター
public void setAmount(int inputAmount) {
        if (this.chkAmount(inputAmount)) {
            this.amount = inputAmount; 
        }
    }

セッター

user1.setAmount(11);はsetterを使いamountの値を変更する
Mainクラスはuser1の参照先であるid=〇〇で管理されたuserオブジェクトに対してsetAmountメソッドを実行し、必要な値として11を渡す。
setAmountメソッドの中に入るとsetAmountのchkAmountメソッドが実行され、その中のchkAmountメソッドで0以上ならtrue,それ以外ならfalseを返す。今回は11でtrueなのでthis.amount = inputAmountがそのまま実行されてuser1オブジェクトのamountの値が書き換わる。
0以下の数値でfalseを返した場合、何も値は渡されずそのままになる。

ゲッター

String aaa = user1.getUserName();
getterを使うことでデバッグでuser1に登録されてる値を変数にいれて確認することができる。
今回はstring型のuserNameを確認したいのでmainクラスはuser1の参照先であるid=〇〇のオブジェクトに対してgetUserNameという振る舞いをおねがいします。

getUserNameの中に入ると自分自身のuserNameを戻り値でかえした結果

public String getUserName() {
        return userName;
    }

右側はuserNameの値になり、変数aaaに値がセットされる。

List

List<User> userList = new ArrayList<>();
mainクラスはuserListを型引数E(User型)としての配列として扱うと決めてArrayListクラスをnewした結果をuserListの中にid=〇〇のArrayListオブジェクトのリストとして返す。

userList.add(user1);
userListに入っているid=〇〇で管理されたArrayListオブジェクトに対してaddメソッドを実行する
addメソッドの中にはいるとmain側の引数からパラメータに値をひっぱってきてるのでeには引数で定義したuser1のアドレスがはいっていることがわかる

addメソッド

 public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

thisをみると配列[0]がはいりuser1の参照先であるid=〇〇のuserオブジェクトのアドレスがはいっていることがわかるのでuserListに配列[0]がはいる

拡張for文

for(User tarUser : userList) {
    tarUser.rankJudge();
    tarUser.output();
        }

追加したUserListをforで順番にまわすにはUser型のtaruserという変数にuserListの配列[user1,user2,user3]から1つずつ要素をとりだして、変数tarUserへ代入し出力させます
変数tarUserにuserListの[0]がはいり、id=〇〇で管理されたuserオブジェクトに対してrankjudge,outputメソッドが実行される

Userクラス

public class User {
    private String userName;
    private int amount;
    private String ranking;

    /**
    * Userの入力用メソッド(引数有コンストラクタ)
    * @param inputName inputする名前情報
    * @param inputAmount inputする売上情報 
    */  
    public User (String inputName, int inputAmount) {
        this.userName = inputName;
        if (this.chkAmount(inputAmount)) {
            this.amount = inputAmount; 
        }else {
            this.amount = 0;
        }
    }
//chkAmountメソッド
//コンストラクタとセッターで2つchkを書いているので
//重複を防ぐためにさらにメソッド化する
    private Boolean chkAmount (int chkAmoumt) {
        if(chkAmoumt > 0) {
            return true;
        }else{
            return false;
        }
    }
    public void setAmount(int inputAmount) {
        if (this.chkAmount(inputAmount)) {
            this.amount = inputAmount; 
        }
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAmount() {
        return amount;
    }

    public String getRanking() {
        return ranking;
    }

    public void setRanking(String ranking) {
        this.ranking = ranking;
    }

    //引数なしコンストラクタ
    public User() {

    }


    /**
    * rankJudgeメソッド 
    * Userの売上額から、顧客ランク設定を行う
    * 
    */
    void rankJudge() {
        if (amount >= 80) {
            ranking = "お得意様";
        } else if (amount >= 60){
            ranking = "常連様";
        } else if (amount >= 40) {
            ranking = "新規顧客";
        } else {
            ranking = "冷やかし客";
        }

    }
    /**
    * outputメソッド 
    * User情報出力用メソッド
    * 
    */
    void output() {
        System.out.println("名前:" + userName);
        System.out.println("売上:" + amount);
        System.out.println("顧客ランク:" + ranking);

    }
}