Java/[inflearn] 자바 기본

[김영한_자바기본][2.기본형과 참조형] 상품 주문 시스템 개발_문제 풀이 해석 보충 (p.30-34)

줌인. 2024. 2. 6. 13:33
중간 변수 없이 참조값 자체를 배열로 전달할 수 있으며, 
배열을 매개변수로 받으면 배열 내 요소를 반복 출력할 수 있다.
또한 입력받은 값은 배열에 담기위한 작업을 수행하고, 기존 코드를 기반으로 응용하면 된다.

 

 

 


*문제 풀이_상품 주문 시스템 개발

 

[p.30 / ProductOrder Class]

public class ProductOrder {
    String productName;
    int price;
    int quantity;
}

 

>> 출력예시

상품명: 두부, 가격: 2000,수량: 2
상품명: 김치, 가격: 5000, 수량: 1
상품명: 콜라, 가격: 1500, 수량: 2
총 결제 금액: 12000

 

 

[p.31 / ProductOrderMain class]

public static void main(String[] args) {
    ProductOrder[] orders = new ProductOrder[3]; 
    ProductOrder order1 = createOrder("두부", 2000, 2); 
    orders[0] = order1;

    ProductOrder order2 = createOrder("김치", 4000, 1);
    orders[1] = order2;

    ProductOrder order3 = createOrder("콜라", 1500, 2);
    orders[2] = order3;

    printOrders(orders);
}


static ProductOrder createOrder(String productName, int price, int quantity) {
    ProductOrder order = new ProductOrder();
    order.productName = productName;
    order.price = price;
    order.quantity = quantity;
    return order;
}

static void printOrders(ProductOrder[] orders) {
     for (ProductOrder order : orders) { 
        System.out.println("상품 : " + order.productName + 
                          ", 가격 : " + order.price + ", 수량 : " + order.quantity);
    }
}

static int getTotalAmount(ProductOrder[] orders) {
    int sum = 0;
    for (ProductOrder order : orders) {
        sum += (order.price * order.quantity);
    }
    return sum;
}

 


상기 코드 분해해보기

 

[p.31 / ProductOrderMain의 Main코드 분석_주석 참고]

public static void main(String[] args) {
    //orders는 ProuductOrder타입의 order변수를 담을 수 있는 공간 --> order형 변수를 묶음 배열로(코드/관리 위함)
    ProductOrder[] orders = new ProductOrder[3]; //orders[0] = order1 --> 배열 저장 그림
    ProductOrder order1 = createOrder("두부", 2000, 2); //orders[0]
    orders[0] = order1;
    //여기서도 보면 crateOrder()기능은 데이터가 들어가나 호출자에는 위치만 부여되고, 배열은 그 위치만 전달받는다.

    ProductOrder order2 = createOrder("김치", 4000, 1);
    orders[1] = order2;

    ProductOrder order3 = createOrder("콜라", 1500, 2);
    orders[2] = order3;
    //ProductOrder order1 이라는 코드는 ProductOrder의 배열안으로 들어가게 됨
    //그 이유는 ProductOrder이라는 타입을 가진 order형 변수의 집합들은 ProductOrder 배열 변수로 들어가기 때문
    //따라서 이러한 구조의 이해를 돕기 위해 orders[i] = orderi(중간변수)를 사용해 표기했다.
    printOrders(orders);
}

- ProductOrderMain 클래스에서 main 메서드에서 ProductOrder 배열인 orders를 생성하고,

  각각의 주문 정보(order1, order2, order3)를 생성한 후 해당 배열의 각 인덱스에 저장한다.

  ∴ 주문 정보가 배열의 묶음, 소속이기 때문이다.

- 실제 orders[i] 에는 객체의 참조값이 담기게 된다. 

 

 

↓ 해당 코드를 더 깔끔하게 만들기 위해선? ↓

 

 

[p.31 / ProductOrderMain의 Main 수정 코드 분석] 중간 변수 없이 참조값 자체를 배열로 전달할 수 있다.

public static void main(String[] args) {
    ProductOrder[] orders = new ProductOrder[3]; //orders[0] = order1 --> 배열 저장 그림 그리기
    //ProductOrder order1 이라는 코드는 ProductOrder의 배열안으로 들어가게 됨
    //그 이유는 ProductOrder이라는 타입을 가진 order형 변수의 집합들은 ProductOrder 배열 변수로 들어가기 때문

    orders[0] = createOrder("두부", 2000, 2); //orders[0]
    orders[1] = createOrder("김치", 4000, 1);
    orders[2] = createOrder("콜라", 1500, 2);

    //따라서 orders[i] = orderi(중간변수)로 표기할수도 있음
    //그러나, 생략해 자체적으로 배열에 할당하는 것이 더 많이 사용되고, 깔끔하다.
    //즉 orders[0]은 createOrder을 담을수도 있다.

    printOrders(orders);
}

- 즉 참조값을 중간변수 없이 바로 전달할 수 있다.

- 이러한 것이 코드의 효율성을 높인다.

 

[p.31 / CreateOrder 메서드 생성과 상기 Main 메서드 연결]

//상품 주문 정보 생성 -->> (배열에 저장)
static ProductOrder createOrder(String productName, int price, int quantity) {
    ProductOrder order = new ProductOrder();
    order.productName = productName;
    order.price = price;
    order.quantity = quantity;
    return order;
}

- 상품 주문 정보가 생성되면 order이라는 객체 변수(참조값이 담겨 있음)가 생긴다.

- 이를 보관하기 위해선 수정 전 코드는 ProductOrder order1 = new ProductOrder에 담았다.

- 하지만 order1은 orders 배열안의 코드이므로 중간변수를 생략해 orders[0] = order1에 담게 된 것이다.

-  이렇게 하면 코드가 간결해지고, 중간 변수를 사용하지 않아도 되므로 가독성이 향상된다.

-  즉 배열에 주문 정보를 저장하는 것이 새로운 주문 정보를 생성하고 저장하는 흐름을 명확하게 표현할 수 있다.

 

[p. 31 / printOrders 메서드 생성과 이해] 배열을 매개변수로 받으면 배열 내 요소를 반복 출력할 수 있다.

//파라미터를 전달받아야하는 이유,, --> 배열값 출력,,,
static void printOrders(ProductOrder[] orders) {
    //printItems 메서드에서 orders.length를 사용하려면 orders 배열이 메서드의 매개변수로 전달되어야 한다.
    //현재 printItems 메서드는 어떤 매개변수도 받지 않고 있기 때문에 orders 배열을 인식하지 못한다.
    //따라서 배열 안의 코드 반복작업을 위해 ProductOrder[] orders 매개변수를 추가한다.
     //배열에 저장되어있기 때문에 배열 내용을 출력해서 객체 참조를 불러야 값을 확인할 수 있다.
    for (ProductOrder order : orders) {
        //for(int i = 0; i < orders.length ; i++) - order이라는 변수 자체가 orders[i]
        System.out.println("상품 : " + order.productName + ", 가격 : " + order.price +
                ", 수량 : " + order.quantity);
    }
}

- `printOrders` 메서드는 `ProductOrder` 타입의 배열을 매개변수로 받아와서 배열 내의 주문 정보를 출력한다.

- 배열이 메서드의 매개변수로 전달되면 받은 배열을 이용하여 배열 내의 각 요소를 반복하며 출력할 수 있다.
-  만약 메서드가 매개변수로 배열을 받지 않고 외부에 정의된 배열에 의존한다면,

    메서드 내에서 배열의 길이를 사용하기 어렵다.

- 이렇게 하면 메서드는 어떤 배열이든 받아들일 수 있고, 배열의 길이 등을 활용할 수 있게 됩니다.

 

[p.31 / getTotalAmount 메서드 생성]

//배열값 출력과 동일하게 작동
static int getTotalAmount(ProductOrder[] orders) {
    int sum = 0;
    for (ProductOrder order : orders) { 
        sum += (order.price * order.quantity);
    }
    return sum;
}

 

 

 


*문제 풀이_상품 주문 시스템 개발 : 사용자 입력

 

>> 출력예시 (주문의 수량개수를 입력받아야 한다)

입력할 주문의 개수를 입력하세요: 3
1번째 주문 정보를 입력하세요.
상품명: 두부
가격: 2000
수량: 2

2번째 주문 정보를 입력하세요.
상품명: 김치
가격: 5000
수량: 1

3번째 주문 정보를 입력하세요.
상품명: 콜라
가격: 1500
수량: 2

상품명: 두부, 가격: 2000, 수량: 2
상품명: 김치, 가격: 5000, 수량: 1
상품명: 콜라, 가격: 1500, 수량: 2
총 결제 금액: 12000

 


 

[p.33 / ProductOrderMain의 Main 코드 분석] Scanner로 입력받은 것을 배열에 담기 위해 작업한다.

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("입력할 주문의 개수를 입력하세요 : ");
    int count = scanner.nextInt();
    scanner.nextLine();

    ProductOrder[] orders = new ProductOrder[count];
    for (int i = 0; i < count ; i++) { //순번과 상품명 ~ 수량 입력 버튼이 반복됨
        System.out.println((i+1) + "번째 주문 정보를 입력하세요");
        System.out.print("상품명 : ");
        String productName = scanner.nextLine(); //원래 createOrder에 들어가는 정보들 자리다.
        //createOrder 구조를 생각해서 이름을 입력하면 된다.

        System.out.print("가격 : ");
        int price = scanner.nextInt();

        System.out.print("수량 : ");
        int quantity = scanner.nextInt();

        //입력된 정보가 배열에 담겨야 한다.
        //기존 코드 : orders[0] = createOrder("두부", 2000, 2); 떠올리자
        orders[i] = createOrder(productName, price, quantity); //지역변수의 값이 담기는 것
    }
    printOrders(orders);
    System.out.println("총 결제 금액 : " + getTotalAmount(orders));
}

- 주문 정보를 입력받을 때 `Scanner`를 사용하여 각 항목의 값을 입력받고,

   그 값을 이용하여 `createOrder` 메서드를 호출해 `ProductOrder` 객체를 생성한 후 배열에 저장한다.
- `orders[i] = createOrder(productName, price, quantity);`는 `createOrder` 메서드에 들어가는 값들이

   `Scanner`를 통해 입력받은 지역 변수들의 값들로 구성됩니다.

   ⇒ 해당 부분이 헷갈린다면 createOrder부분부터 보고 나눠 생각하자

생성된 `ProductOrder` 객체는 배열 `orders`의 각 인덱스에 저장되어 전체 주문 정보가 배열에 담긴다.

 

 

 

 

 

▶ 문제 풀이 1단계 (심화 이해를 이해선 본문을 참조하면 된다.)

https://zoooom-in.tistory.com/49

 

[김영한_자바기본][2.기본형과 참조형] (보충) 기본형 / 참조형 - 메서드, 문제 풀이 해석 (p.11-20, p.

▶ 기본형과 참조형 이해 https://zoooom-in.tistory.com/45 [김영한_자바기본][2.기본형과 참조형] 기본형 / 참조형 이해 (p.1-6) 참조값에 접근한다는 것은 설계도와 부지 위치에 접근해서 같이 공동 작업

zoooom-in.tistory.com

 

 

▶ 배열의 선언과 생성 이해하기

https://zoooom-in.tistory.com/44

 

[김영한_자바입문][9.배열] 배열의 선언과 생성 이해하기 (p.2-7)

배열 선언은 아파트 부지 확보, 생성은 몇 개의 아파트를 확보할 것인지 배열의 값 할당은 부지를 참조해 실제 준공일을 기입한다. 할당 전까지는 부지 주소만 참조되어 나타난다. [코드 읽기 전

zoooom-in.tistory.com

 

728x90