JPIN#5
オブジェクト型配列
配列の宣言を確認してみよう
int [] array = new int[3];
この文章を砕けて説明すると
int [] array → int型配列のarray
new int[3] →
new ヒープにメモリの領域を確保する
ヒープ領域に領域を確保したときはnullの状態
実際にオブジェクト配列を使用したオブジェクトを作ってみよう
ここでは任意の商品ごとの金額と個数と商品名を記憶させて全ての商品の合計金額を計算するオブジェクトを作成する
Itemクラス
まず任意の商品の名前と金額を記憶する、Itemクラスから作成する
public class Item {//Itemクラス ある商品の名前と金額を覚えて記憶 private String name;//string型のname private int price;//int型のprice public Item(String name, int price) {//Itemメソッド name とpriceを受け取る super(); this.name = name;//Itemクラスにあるnameにitemメソッドのnameを代入 this.price = price;//Itemクラスにあるpriceにitemメソッドのpriceを代入 } public String getName() {//getNameメソッド return name;//nameを返す } public int getPrice() {//getPriceメソッド return price;//priceを返す } }
ここでitemクラスのItemメソッドが呼び出された時にStirng型とint型を受けとって名前と金額を記憶することができる
Orderクラス
続いて上記クラスで覚えた商品の個数を記憶するOrderクラスを作成する
public class Order {//OrderクラスはItemクラスの商品の名前と数を記憶する private Item item;//Item型のitem private int qty;//int型のqty public Order(Item item, int qty) {//itemとqtyをうけとるOrderメソッド super(); this.item = item;//OrderクラスのitemにOrderメソッドのitemを代入 this.qty = qty;//OrderクラスのqtyにOrderメソッドのqtyを代入 } public int getQty() {//getQtyメソッド return qty;//qtyを返す } public int getTotal() { //getTotalメソッド return item.getPrice() * this.qty;//Itemクラスのprice×個数(qty)、つまりある商品の合計金額を返す } }
ここではItem型(Itemクラスの値)とint型(個数)を受け取ることで商品の個数と商品の合計金額を算出して記憶することができる
ShoppingCartクラス
次に上記のクラスを使用して覚えた各商品の合計金額を足して全ての商品の合計金額を算出するShoppingCartクラスを作成する
public class ShoppingCart {//ShoppingCartクラス private Order[] orders = new Order[10];//Orderクラスのコピーを11個分ヒープ領域に確保 private int index = 0;//int型index=0 public void add(Order order) {//addメソッド Order型の変数を受け取る orders[index] = order;//oreders[index],つまりヒープ領域にあるindex番目のOrderクラスに受け取ったorderを代入 index++;//indexを+1 } public int getTotal() {//getTotalメソッド int total = 0;//int型total=0 for(int i = 0; i < index; i++) {//0からindexまでループ(ここでindexは11までしか行かないことはオブジェクト配列の個数で分かる) total = total + orders[i].getTotal();//orders[i],つまりorderを足していく } return total;//totalを返す } }
ここでは上記のOrderクラスをそれぞれの商品ごとでオブジェクト配列にして合計金額を算出している
Mainクラス
最後にこれを動かすためのMainクラスを作成する
public class Main { public static void main(String[] args) {//mainメソッド Item o = new Item("orange", 50);//itemクラスのコピーにorangeと金額50を渡す Order order1 = new Order(o, 3);//Orderクラスのコピーにo,つまり上記のItemクラスの値と個数3を渡す ShoppingCart s = new ShoppingCart();//ShoppingCartクラスのコピーを作成する s.add(order1);//上記ShoppingCartクラスコピーに上記Orderクラスを渡してaddメソッドを実行する Item a = new Item("apple", 120);//Itemクラスのコピーにappleと金額120を渡す Order order2 = new Order(a, 5);//Orderクラスのコピーに上記Itemクラスの値と個数5を渡す s.add(order2);//ShoppingCartクラスのコピーに上記Orderクラスの値を渡してaddメソッドを実行する Item b = new Item("banana", 80);//Itemクラスのコピーにbananaと金額80を渡す Order order3 = new Order(b, 8);//Orderクラスのコピーに上記Itemクラスの値と個数8を渡す s.add(order3);//ShoppingCartクラスのコピーに上記Orderクラスを渡してaddメソッドを実行する System.out.println(s.getTotal());//ShoppingCartクラスのコピーにあるgetTotalメソッドを出力する } }
ここではそれぞれのクラスに渡す値を決めてそれを取りまとめて実行している
これで実行すると
1390
となる
ではこのMainクラスからもう少し細かく読み取っていこう
どうやって動いてる??
まず最初にitemクラスのコピーをヒープ領域に作り、そのクラスのItemメソッドにStirng型”orange"とint型50を渡している
そしてそのクラスの参照アドレスを"o"としている(Item型のo)
ここでItemクラスを見てみよう
ItemクラスにあるItemメソッドに"orange”と50を渡した後にItemクラスで宣言しているprivateのnameに”orange"を、privateのpriceに50を代入している
privateにすることによってメソッドを起動しないと変数を変更できないようにしている
これによってカプセル化が成立している
Mainクラスに戻ろう
次にOrderクラスのコピーをヒープ領域に作り、そのクラスのOrderメソッドにItem型"o"とint型3を渡している
そしてそのクラスの参照アドレスを”order1”としている(Order型のorder1)
ここで"o"は先ほど作ったItemクラスのコピーに"orange”と50を入れたものである
Orderメソッドでも同様にOrderクラスで宣言されたprivateのそれぞれの型の中に代入することでカプセル化している
そしてgetTotalメソッドでは”orange”の小計を返している
Mainクラスに戻ろう
次にShoppingCartクラスのコピーをヒープ領域に作りその参照アドレスを”s”としている
そしてsのaddメソッドにOrder型のorder1を代入している
ここでorder1は先ほどitemクラスとint型を代入したものである
ShoppingCartクラスを見てみよう
ここでは最初にprivateでOrder型の配列を宣言している
この時にヒープ領域には11個分のOrderクラスのコピーが作成される(※渡す値はnull)
そしてaddメソッドではorder1が渡されて、先ほど宣言したprivateのOrderクラスの配列の0番目(indexの初期値が0だから)にorder1を代入している
その後にindexを+1している
Mainクラスに戻ろう
次にまたItemクラスのヒープ領域を作る
ここからは先ほどと同じで最初にItemクラスにある値を代入したもののコピーをヒープ領域に作り、それをOrderクラスに代入、さらにそのOrderクラスをShoppingCartクラスに代入している
ここでShoppingCartクラスを見てみよう
最初にOrderクラスを代入したときはindexは0だったのでorders[0]にorder1が代入された
そしてその後にindexは+1されているのでこのときはorders[1]にorder2が代入される
このようにしていきorder3まで作ってaddメソッドに代入した後にsにあるgetTotalメソッドを見てみよう
ShoppingCartクラスのgetTotalメソッドではOrdr型配列の各要素クラスにあるgetTotalメソッドを足している
OrderクラスのgetTotalメソッドではOrderメソッドに代入されたItemクラスの商品の小計が記憶されているのでShoppgCartクラスのgetTotalメソッドでは全ての商品の合計金額がわかる
そのような流れで任意の商品達の合計金額を算出することができる
ヒープ領域はいくつ作られた???
結局このオブジェクトではヒープ領域に以下のクラスのコピーが作られている
Itemクラス("orange",50)略称"o",
Itemクラス("apple",120)略称"a",
Itemクラス("banana",80)略称"b"の3つ
Orderクラス("o",3)略称"order1",
Orderクラス("a",5)略称"order2",
Orderクラス("b",8)略称"order3"の3つ
ShoppingCartクラス1つ(order1とorder2とorder3を代入)
Shopping Cartクラスで宣言されたオブジェクト型配列orders 要素が11個なのでOrderクラスのコピーが11個
合計18個である
大事なポイント
・これはそれぞれヒープ領域にコピーされたもので値を渡したり受け取っていることをよく認識しておこう!
・privateを使って簡単に他から値を受け取らないようにカプセル化しよう!