본문 바로가기
JAVA

데이터 구조화

by 영카이브 2024. 1. 7.

 

재고관리를 위해 상품을 입력하고 입력한 상품들을 볼 수 있도록 출력하는 프로그램 로직 구현 과정 

 

참조변수

  • 참조변수는 객체를 식별하는 이름이다. 
  • 참조변수는 기본적으로 null을 가진다.
  • 참조변수에 new를 통해서 만든 객체에 대입해야한다.

 

Product라는 사용자가 정의한 구조형식의 데이터를 가지고 변수를 만들고 선언하여 객체를 만들어 참조시키고 공간을 이용해 값을 대입하고 그 값을 출력한다.

 

위 문장대로 코드를 짜보자.

 

1. Product라는 사용자가 정의한 구조형식의 데이터를 가지고

public class Product {
	String name; 
	int price; 
	int quantity;
}

 

 

2. 변수를 만들고 : Product product 

3. 선언하여 : = 

4. 객체를 만들어 참조시키고 : new Product();

5. 공간을 이용해 값을 대입하고 : product.name="티셔츠"; product.price=300000; product.quantity=100;

6. 그 값을 출력 : System.out.printf("price : " + product.price);

 

public class ProductProgram {
	public static void main(String[] args) {
		Product product = new Product();
		product.name="티셔츠";
		product.price=300000;
		product.quantity=100; 
		System.out.printf("price : " + product.price);
	}
}

 

 

 

이번에는 값을 직접 대입하지말고 상품 1종류만 재고에 입력 및 출력 하려고 한다. 

 

public class Product {
	String name;
	int price; 
	int quantity;
}

 

public class InventoryProgram {
	public static void main(String[] args) {
		Product product = new Product();
		addInventory(product);
		displayInventory(product);
	}
	private static void addInventory(Product product) {
		Scanner sc = new Scanner(System.in);
		System.out.println("상품 입력");

		String name; 
		int price, quantity;
		
		System.out.printf("상품 이름 : "); 
		name=sc.next();
		do {
			System.out.printf("가격 : ");
			price=sc.nextInt();
			if(price<0) {
				System.out.println("가격은 0보다 커야합니다.");
			}
		}while(price<0);
		do {
			System.out.printf("수량 : ");
			quantity=sc.nextInt();
			if(quantity<0) {
				System.out.println("수량은 0보다 커야합니다.");
			}
		}while(quantity<0);
		product.name=name;
		product.price=price;
		product.quantity=quantity;
		
	}
	private static void displayInventory(Product product) {
		System.out.println("상품 출력");
		String name=product.name;
		int price=product.price;
		int quantity=product.quantity;
		System.out.println( "상품 이름 : " + name);
		System.out.println( "상품 가격 : " + price);
		System.out.println( "상품 수량 : " + quantity);
	}
}

 

 

 


 

클래스 배열

  • 클래스 배열은 참조형식의 배열이고 이를 만들게되면 주소를 저장할 수 있는 형태만 만들어진다.
  • 객체 배열이 아닌 객체 참조 배열이다.
public static void main(String[] args) {
		Product[] products = new Product[5];
		products[0] = new Product();
		products[0].name="회색티";
	}
  1. Product[] products = new Products[5]; :  new를 하는 순간  Product형식의 배열 5개가 만들어진다.
  2. products[0].name="회색티";는 불가능하다.
  3. products[0] = new Product();로 객체를 대입해줘야만 그 때 name,price,quantity 공간이 만들어진다. 

 

5로 고정된 Product클래스 배열을 가지고 상품입력 및 상품출력을 하려고한다.

 

import java.util.Scanner;

public class Program {
	public static void main(String[] args) {
		Product[] products = new Product[5];
		int menu; 
		boolean keepLoop=true;
		
		while(keepLoop) {
			menu=inputMenu();
			switch(menu) 
			{
			case 1:
				addInventory(products);
				break; 
			case 2 :
				displayInventory(products);
				break;
			case 3 : 
				System.out.println("종료");
				keepLoop=false;
				break;
			default :
				System.out.println("메뉴는 1~3번까지 입니다.");
			}
			
		}
	}

	private static int inputMenu() {
		Scanner sc = new Scanner(System.in);
		System.out.println("1.상품 입력 ");
		System.out.println("2.재고 출력 ");
		System.out.println("3.종료");
		int menu=sc.nextInt();
		return menu;
	}
	private static void addInventory(Product[] products) {
		Scanner sc = new Scanner(System.in);
		System.out.println("상품 입력");

		String name; 
		int price, quantity;
		
		for( int i=0; i<5; i++ ) {
			System.out.printf("상품 이름 : "); 
			name=sc.next();
			do {
				System.out.print("가격 : ");
				price=sc.nextInt();
				if(price<0) {
					System.out.println("가격은 0보다 커야합니다.");
				}
			}while(price<0);
			do {
				System.out.print("수량 : ");
				quantity=sc.nextInt();
				if(quantity<0) {
					System.out.println("수량은 0보다 커야합니다.");
				}
			}while(quantity<0);
			Product product = new Product();
			product.name=name;
			product.price=price;
			product.quantity=quantity;
			products[i] = product; 
		}
		
		
	}
	private static void displayInventory(Product[] products) {
		System.out.println("상품 출력");
		for( int i=0; i<5; i++) {
			Product product = products[i]; 
			String name=product.name;
			int price=product.price;
			int quantity=product.quantity;
			System.out.println( "상품 이름 : " + name);
			System.out.println( "상품 가격 : " + price);
			System.out.println( "상품 수량 : " + quantity);
		}		
	}
}

 

  • 상품을 입력하는 addInventory() 에선 Product객체를 new한 뒤 값을 대입하고 이 product객체가 가리키는 주소를 Product[i] 변수에 대입하여 공유할 수 있도록 하였다.
  • 상품을 출력하는 displayInventory()에선 products i번째 인덱스에 있는 Product 객체를 가져와서 product라는 변수에 할당하였다. 

 

가변 길이 배열

  • 최소한의 크기를 잡고 필요에 따라 크기를 늘리는 것이 좋다. 
  • Product객체를 딱 5개 참조하도록 만들었기때문에 그 이상 입력 할 시 ArrayIndexOutOfBoundsException 발생한다.
  • 배열은 고정된 길이를 가지며 자동으로 늘어나지 않는다. 
  • 필요한 크기의 또 다른 배열을 만들어서 그 값을 이동시키고 원래 배열은 소거하는 방법을 사용해야한다
  • current는 값이 들어간 배열의 마지막 인덱스값이다. 
  • current는 참조변수가 아닌 값변수이므로 Product배열 처럼 공유되지않고 값만 함수에 전달하게 된다. 따라서 current값을 함수 안에서 증가시키면 거기에서만 적용되고 함수가 종료되면 current값은 변함없이 0이다. 
  • 즉 함수 단위에서 서로 공유해야할 데이터는 큰 단위의 구조체로 묶는다. >>> Inventory 클래스
public class Inventory {
	Product[] products;
	int current; 
}
public class InventoryProgram {
	public static void main(String[] args) {
		Inventory inventory = new Inventory(); 
		inventory.products = new Product[5]; 
		inventory.current=0; 
		int menu; 
		boolean keepLoop=true;
		
		while(keepLoop) {
			menu=inputMenu();
			switch(menu) 
			{
			case 1:
				addInventory(inventory);
				break; 
			case 2 :
				displayInventory(inventory);
				break;
			case 3 : 
				System.out.println("종료");
				keepLoop=false;
				break;
			default :
				System.out.println("메뉴는 1~3번까지 입니다.");
			}
			
		}
	}

	private static int inputMenu() {
		Scanner sc = new Scanner(System.in);
		System.out.println("1.상품 입력 ");
		System.out.println("2.재고 출력 ");
		System.out.println("3.종료");
		int menu=sc.nextInt();
		return menu;
	}
	private static void addInventory(Inventory inventory) {
		Scanner sc = new Scanner(System.in);
		System.out.println("상품 입력");
		
		String name; 
		int price, quantity;
		
		System.out.printf("상품 이름 : "); 
		name=sc.next();
		do {
			System.out.print("가격 : ");
			price=sc.nextInt();
			if(price<0) {
				System.out.println("가격은 0보다 커야합니다.");
			}
		}while(price<0);
		do {
			System.out.print("수량 : ");
			quantity=sc.nextInt();
			if(quantity<0) {
				System.out.println("수량은 0보다 커야합니다.");
			}
		}while(quantity<0);
		Product product = new Product();
		product.name=name;
		product.price=price;
		product.quantity=quantity;
		
		Product[] products = inventory.products; 
		int size = inventory.current; 
		
		if(products.length==size) {
			// 1.크기가 3개정도 더 큰 새로운 배열을 생성
			Product[] temp = new Product[size+3]; 
			// 2.값을 이주 
			for( int i=0; i<size; i++) {
				temp[i]=products[i]; 
			}
			// 3.inventory.products가 새로 만든 temp배열을 참조
			inventory.products = temp; 
		}
//		products[size]=product;
//		size++; 
		products[size]=product;
		inventory.current++;
	}
	private static void displayInventory(Inventory inventory) {
		System.out.println("상품 출력");
		int size=inventory.current; 
		System.out.println("size : " + inventory.current);
		for( int i=0; i<size; i++) {
			Product product = inventory.products[i]; 
			String name=product.name;
			int price=product.price;
			int quantity=product.quantity;
			System.out.println( "상품 이름 : " + name);
			System.out.println( "상품 가격 : " + price);
			System.out.println( "상품 수량 : " + quantity);
		}		
	}
}

 

 

products[size]=product;

size++;

가 틀리고

products[size]=product;

inventory.current++;

가 맞는 이유는?

 

int size = inventory.current;는 inventory.current의 현재 값을 size에 복사하는 것이다.

그 이후에 size++를 하더라도 inventory.current에는 아무런 영향을 미치지 않는다.

즉, size와 inventory.current는 서로 다른 변수이므로 한 쪽을 증가시켜도 다른 쪽에는 영향을 주지 않는다.

 


 

overload함수

  • 인자는 다르고 같은 이름의 함수를 말한다.
  • 인자가 많아져 사용자를 위해 좀더 세밀한 옵션을 가진다.
  • 함수명이 같다는 것은 기능이 같다는 뜻이며 수정이 필요할 시 기본함수와 overload함수가 같이 수정되어야 한다.
  • 따라서 overload함수가 꼭 생각해야 할 것은 집중화다.
  • 인자가 적은 쪽이 구현을 다 하는 것이 아니라 overload함수를 호출한다.

 

기본함수는 current 값 만큼 출력한다. 

overload함수는 current값과 상관없이 2개만 출력하고 싶다. 

 

 

public class InventoryProgram {
	public static void main(String[] args) {
		Inventory inventory = new Inventory(); 
		inventory.products = new Product[5]; 
		inventory.current=0; 
		int menu; 
		boolean keepLoop=true;
		
		while(keepLoop) {
			menu=inputMenu();
			switch(menu) 
			{
			case 1:
				addInventory(inventory);
				break; 
			case 2 :
				// 기본 함수
				displayInventory(inventory);
				// overload 함수
				displayInventory(inventory,2);
				break;
			case 3 : 
				System.out.println("종료");
				keepLoop=false;
				break;
			default :
				System.out.println("메뉴는 1~3번까지 입니다.");
			}
			
		}
	}

	private static int inputMenu() {
		Scanner sc = new Scanner(System.in);
		System.out.println("1.상품 입력 ");
		System.out.println("2.재고 출력 ");
		System.out.println("3.종료");
		int menu=sc.nextInt();
		return menu;
	}
	private static void addInventory(Inventory inventory) {
		Scanner sc = new Scanner(System.in);
		System.out.println("상품 입력");
		
		String name; 
		int price, quantity;
		
		System.out.printf("상품 이름 : "); 
		name=sc.next();
		do {
			System.out.print("가격 : ");
			price=sc.nextInt();
			if(price<0) {
				System.out.println("가격은 0보다 커야합니다.");
			}
		}while(price<0);
		do {
			System.out.print("수량 : ");
			quantity=sc.nextInt();
			if(quantity<0) {
				System.out.println("수량은 0보다 커야합니다.");
			}
		}while(quantity<0);
		Product product = new Product();
		product.name=name;
		product.price=price;
		product.quantity=quantity;
		
		Product[] products = inventory.products; 
		int size = inventory.current; 
		
		if(products.length==size) {
			// 1.크기가 3개정도 더 큰 새로운 배열을 생성
			Product[] temp = new Product[size+3]; 
			// 2.값을 이주 
			for( int i=0; i<size; i++) {
				temp[i]=products[i]; 
			}
			// 3.inventory.products가 새로 만든 temp배열을 참조
			inventory.products = temp; 
		}
		products[size]=product;
		inventory.current++;
	}
	private static void displayInventory(Inventory inventory) {
		// 집중화 코드 
		displayInventory(inventory, inventory.current);
	}
	
	// overload
	// 넘겨받은 size값만큼 출력
	private static void displayInventory(Inventory inventory, int size) {
		System.out.println("상품 출력");
		for( int i=0; i<size; i++) {
			Product product = inventory.products[i]; 
			String name=product.name;
			int price=product.price;
			int quantity=product.quantity;
			System.out.println( "상품 이름 : " + name);
			System.out.println( "상품 가격 : " + price);
			System.out.println( "상품 수량 : " + quantity);
		}		
	}
}

 

 

 

참고 자료 출처 :

https://youtu.be/ghB3e2NWNgE?si=8_FONJ1_dC7xcDsn

https://www.youtube.com/watch?v=x_-IRcsTT_0&list=PLq8wAnVUcTFWQ4TpRPZRa5nj1VwfyO7st&index=14

'JAVA' 카테고리의 다른 글

UI코드 분리 하기  (0) 2024.01.10
Setter 대신 Overload 생성자 이용하기  (0) 2024.01.09
Getter 와 Setter  (0) 2024.01.07
생성자  (0) 2023.12.18
캡슐화  (0) 2023.12.18