おふとんガレージ

技術的な忘備録とか雑記

javaとオブジェクト指向をなんとかしようとした。

オブジェクト指向について色々教えてもらう機会があったのでその内容について自分なりに解釈してまとめてみる。

オブジェクト指向の利点

  • 変更が多く咥えられるプログラムの設計において有効
    • オブジェクトとメソッドの呼び出しの集合として構成される。
    • 受け渡しの部分さえ定義すれば、それぞれのメソッドの中で何を実行しているのか考えなくてもいい。(カプセル化

結果として複数人での開発にも非常に威力を発揮する。

ポリフォーリズムとか継承とかそのへんはいまいち理解できてないから割と早急になんとかしたいとこ。


オブジェクト指向を理解する上でサンプルとしてプログラムを書いてもらったので、その流れに従って具体的な実装について考えてみる。
客1,2(guest1,guest2)がラーメン屋に入り注文、伝票に注文したものと合計金額が返ってくるイメージ。

Main.java
import java.util.ArrayList;
import java.util.List;


public class Main {

    public static void main(String[] args){

        //商品設定
        //ArrayList<型> 大きさが決まっていない配列
        ArrayList<Goods> goodsList = new ArrayList<>();
        goodsList.add(new Goods("ラーメン", 620));
        goodsList.add(new Goods("葱ラーメン", 840));
        goodsList.add(new Goods("餃子", 280));
        Shop noodleShop = new Shop(goodsList);

    //オブジェクト生成
        User guest1 = new User("Guest1");
        User guest2 = new User("Guest2");

        noodleShop.registerUser(Guest1);
        noodleShop.registerUser(Guest2);
        List<Goods> menu = noodleShop.getGoodsList();

        noodleShop.printGoodsList();;

        noodleShop.addIntoMyCart(guest1, menu.get(0));
        noodleShop.addIntoMyCart(guest1, menu.get(2));
        noodleShop.printCarts(guest1);
        System.out.println("guest1 total: " + noodleShop.getTotalPrice(guest1));

        noodleShop.addIntoMyCart(guest2, goodsList2.get(1));
        noodleShop.printCarts(guest1);
        System.out.println("guest2 total: " + noodleShop.getTotalPrice(guest2));

    }

}
Shop.java
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import  java.util.ArrayList;


public class Shop {
    private ArrayList<Goods> goodsList;
    private HashMap<User, Cart> cartMap;

    private String name;


    public Shop(ArrayList<Goods> goodsList) {
        cartMap = new HashMap<>();
        this.goodsList = goodsList;
    }

    /**
     * 商品リストを取得する
     * @return 商品リスト(書き込み不可)
     */
    public List<Goods> getGoodsList() {
        return Collections.unmodifiableList(goodsList);
    }

    /**
     * 入店する
     * @param user 入店するユーザ
     */
    public void registerUser(User user) {
        cartMap.put(user, new Cart());
    }

    /**
     * 商品をカートに入れる
     * @param user カートに入れるユーザ
     * @param goods カートに入れる商品
     */
    public void addIntoMyCart(User user, Goods goods) {
        Cart myCart = cartMap.get(user);
        myCart.add(goods);
    }

    /**
     * ユーザの現在のカートの合計金額を求める
     * @param user 求めたいユーザ
     * @return カートの合計金額
     */
    public int getTotalPrice(User user) {
        Cart myCart = cartMap.get(user);
        int total = 0;
        for (Goods goods : myCart) {
            total += goods.getPrice();
        }

        return total;
    }

    /**
     * ユーザの現在のカートの中身を表示する
     * @param user 求めたいユーザ
     */
    public void printCarts(User user) {
        Cart myCart = cartMap.get(user);
        for (Goods goods : myCart) {
            System.out.println(goods.getName());
        }
    }

    public void printGoodsList(){
        for(int i = 0; i < goodsList.size(); i++) {
            System.out.println("[" + i + "] : " + goodsList.get(i).getName() + ", price: " + goodsList.get(i).getPrice());
        }
    }

}
User.java
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
Goods.java
/**
 * 商品クラス
 */
public class Goods {
    /** 商品価格 */
    private int price;
    /** 商品名 */
    private String name;

    /**
     * 商品を新規作成する
     * @param name 商品名
     * @param price 価格
     */
    public Goods(String name, int price) {
        this.price = price;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public  int getPrice() {
        return price;
    }
}
Cart.java
import java.util.ArrayList;

public class Cart extends ArrayList<Goods>{

    public Cart() {
        super();
    }

}

実行結果

[0] : ラーメン, price: 620
[1] : 葱ラーメン, price: 840
[2] : 餃子, price: 280
ラーメン
餃子
guest1 total: 900
葱ラーメン
guest2 total: 840

Process finished with exit code 0

プログラムについて

大まかな流れとしては

  1. メニュー設定
  2. 開店(オブジェクト生成:new Shop())
  3. guest1,guest2来店(オブジェクト生成:new User())
  4. Shop.registerUserで客ごとに伝票を作成(オブジェクト生成:new Cart())
  5. Shopに対してメニューを要求
  6. Shopはメニューを書き込み不可の形でリストとして返却する
  7. ついでにShopはメニューを表示する
  8. guest1がラーメン、餃子を注文
  9. guest1の注文が伝票に書き込まれる
  10. guest1の注文の合計額を計算して表示

以下guest2においても同様の流れ

例えばこの伝票の合計額を表示する際、消費税を加算する際なんかはShop.getTotalPrice(User user)の中のみに変更を加えるだけで済み、他の処理については変更する必要がないなど、書いたコードがこれまで書いてきたプログラムに比べかなり有効に活かせる印象。

一見あっち行ったりこっち行ったりめんどくさいが、Mainから見るとそれぞれの処理について考えなくてよく、それぞれでどのような処理が行われるのかなんとなく頭に入れておけば、かなりプログラムは追いやすいんじゃないかなって。似たような関数ばっかり定義して追う気分になれない自分の書いてきたプログラムよりかはかなりまとも。

色々あってオブジェクト指向とかjavaとかにかなり嫌悪感がありなんかいろいろ面倒くさいのって印象が強かったのがそれなりに有用性を理解できたとは思う。いかんせん勉強不足感はどうしても否めないのでこれからしっかりみっちり理解していきたいところ。