글 작성자: 취업중인 피터팬
728x90
JDK : 1.8.0_261 버전
JRE : 1.8.0_261 버전
JAVA VERSION : 8 업데이트 261
Eclipse IDE VERSION : 2020-06버전

 

 

목표

과일 판매자와 구매자를 객체관점으로 코드를 구현해 본다.

판매자와 구매자의 상호작용을 main함수에서 구현한다.

 

[판매자]

1. 판매자는 과일 갯수, 판매 수익을 알고 있고 사과의 단가를 정할 수 있다.

2. 판매자는 사과를 파는 행위를 할 수 있다. 

3. 판매자는 자신의 현재 잔액과 사과 갯수를 보여줄 수 있다.

[구매자]

1. 구매자는 자신이 보유한 사과 갯수와 금액을 알고 있다.

2. 구매자는 사과를 사는 행위를 할 수 있다.

3. 구매자는 현재 자신이 보유한 금액과 사과 갯수를 보여줄 수 있다.


 

코드

E06FruitSalesMain1.java

package ex08Class;

//과일 판매를 추상화한 클래스
class FruitSeller{
	int numOfApple = 100; //판매자의 사과 보유 갯수
	int myMoney = 0; //판매 수익
	final int APPLE_RRICE = 1000; //사과의 단가
	/*
	 클래스에서 맴버상수를 선언하는 경우 반드시 선언과 동시에
	 초기화 해야한다. 만약 초기화를 별도로 진행하면 에러가 발생한다.
	 */
	
	//판매자가 사과를 판매하는 행위를 표현한 멤버메소드
	/*
	 1. 구매자로부터 금액을 전달 받는다(매개변수)
	 2. 금액에 해당하는 판매될 사과의 갯수를 구한다.
	 3. 보유한 재고에서 갯수만큼 차감한다.
	 4. 판매수익이 증가한다.
	 5. 구매자에게 판매한 사과의 갯수를 반환한다.
	 */
	public int saleApple(int money) {
		int num = money / APPLE_RRICE;
		numOfApple -= num;
		myMoney += money;
		return num;
	}
	
	//판매자의 현재상태를 출력하는 맴버메소드
	public void showSaleResult() {
		System.out.println("[판매자] 남은 사과 개수 : " + numOfApple);
		System.out.println("[판매자] 판매수익 : " + myMoney);
	}
}
//구매자를 표현한 클래스
class FruitBuyer{
	int myMoney = 5000;//보유 금액
	int numOfApple = 0;//구매한 사고의 갯수
	
	//구매자가 판매자에게 사과를 구매하는 행위를 표현한 맴버 메소드
	/*
	 1. 판매자에게 금액을 지불한다.
	 2. 판매자가 금액에 해당하는 사과의 갯수를 반환해 준다.
	 		반환한 갯수만틈 보유한 사과의 갯수가 증가한다.
	 3. 판매자에게 지불한 금액만큼 차감된다.
	 */
	public void buyApple(FruitSeller seller, int money) {
		numOfApple += seller.saleApple(money);
		myMoney -= money;
	}
	
	public void showBuyResult() {
		System.out.println("[구매자] 현재잔액 : " + myMoney);
		System.out.println("[구매자] 사과갯수 : " + numOfApple);
	}
}


public class E06FruitSalesMain1 {

	public static void main(String[] args) {
		
		FruitSeller seller = new FruitSeller();
		FruitBuyer buyer = new FruitBuyer();
		
		System.out.println("구매행위가 일어나기 전의 상태");
		seller.showSaleResult();
		buyer.showBuyResult();
		
		/*
		 구매자가 판매자에게 5000원을 지불하고 사과를 구매한 행위를 코드도 표현함
		 */
		System.out.println("구매행위가 일어난 후의 상태");
		
		buyer.buyApple(seller, 5000);
		seller.showSaleResult();
		buyer.showBuyResult();
	}

}

 

첫번째 버전입니다. 그렇게 어렵지 않는 코드입니다. 앞의 내용을 잘 숙지했다면 목표를 잘 따라가면 쉽게 코딩할 수 있을겁니다. 문제는 판매자의 사과 보유 갯수와 판매 수익 사과의 단가가 항상 정해져 있다는 겁니다.

판매자1과 판매자2는 사과 보유 갯수와 사과의 단가가 다를 수 있습니다. 하지만 지금 코딩에서는 모든 변수가 상수로 표현되어 있기 때문에 다른 판매자를 표현하는 것이 어렵습니다. 두번째 버전에서 수정해봅시다.

 

E06FruitSalesMain2.java

package ex08Class;

//과일 판매를 추상화한 클래스
class FruitSeller2{
	int numOfApple; //판매자의 사과 보유 갯수
	int myMoney; //판매 수익
	int apple_price; //사과의 단가
	/*
	상수에서 변수로 변경함.
	클래스의 맴버상수로 정의하는 경우 선언과 동시에 초기화해야 하므로 상수는 초기화 없는
	형태로는 선언이 불가능함.
	 */
	
	/*
	 apple_price를 상수에서 변수로 변경한 이유는 상수는 단 한번만
	 초기화 되는 특성 때문에 일반적인 맴버메소드 내에서는 초기화 할 수 없다.
	 맴버 메소드는 개발자가 원할때 언제든지 호출 할 수 있으므로, 상수의 특정과는
	 맞지 않기 때문이다.
	 */
	public void initMembers(int money, int appleNum, int price) {
		myMoney = money;
		numOfApple = appleNum;
		apple_price = price;
	}

	public int saleApple(int money) {
		int num = money / apple_price;
		numOfApple -= num;
		myMoney += money;
		return num;
	}
	//판매자의 현재상태를 출력하는 맴버메소드
	public void showSaleResult() {
		System.out.println("[판매자] 남은 사과 개수 : " + numOfApple);
		System.out.println("[판매자] 판매수익 : " + myMoney);
	}
}




//구매자를 표현한 클래스
class FruitBuyer2{
	int myMoney = 5000;//보유 금액
	int numOfApple = 0;//구매한 사고의 갯수
	
	public void initMembers(int _myMoney, int _numOfApple) {
		myMoney = _myMoney;
		numOfApple = _numOfApple;
		
	}
	public void buyApple(FruitSeller2 seller1, int money) {
		numOfApple += seller1.saleApple(money);
		myMoney -= money;
	}
	
	public void showBuyResult() {
		System.out.println("[구매자] 연재잔액 : " + myMoney);
		System.out.println("[구매자] 사과갯수 : " + numOfApple);
	}
}


public class E06FruitSalesMain2 {
	
	public static void main(String[] args) {
		
		/*
		 초기화 메소드를 정의하였으므로, 각각 성격이 다른 객체들을 생성할 수 있다. 
		 */
		//판매자 1 : 보유갯수가 100개 단가 1000원
		FruitSeller2 seller1 = new FruitSeller2();
		seller1.initMembers(0, 100, 1000);
		
		//판매자 2 : 보유갯수 80개 단가 500원
		FruitSeller2 seller2 = new FruitSeller2();
		seller2.initMembers(0, 80, 500);
		
		
		FruitBuyer2 buyer = new FruitBuyer2();
		buyer.initMembers(10000, 0);
		
		
		System.out.println("구매행위가 일어나기 전의 상태");
		seller1.showSaleResult();
		seller2.showSaleResult();
		buyer.showBuyResult();
		
		//판매자1, 판매자2에게 각각 5000원을 지불하고 구매
		buyer.buyApple(seller1, 5000);
		buyer.buyApple(seller2, 5000);
		
		
		System.out.println("구매행위가 일어난 후의 상태");
		seller1.showSaleResult();
		seller2.showSaleResult();
		buyer.showBuyResult();
	}

}

 

initMembers() 함수를 통해서 이제부터는 변수를 지정할 수 있게 되었습니다. 하지만 이렇게 함수를 만들게 되면 판매자와 구매자와 서로 상호 작용을 맺고 있는 상황에서 초기화 함수를 호출 할 수 있습니다. 이렇게 된다면 판매자와 구매자는 제대로된 정보를 받을 수 없을지도 모릅니다. 객체를 생성할 때 딱 한번만 변수를 초기화 할 수 있는 함수가 있었으면 좋겠습니다. 그 후에는 변수를 변경할 수 없도록 하기 위해서 말이죠. 그게 바로 생성자이고 생성자를 쓰는 이유입니다. 버전 3번에서 고쳐줍시다.

 

E06FruitSalesMain3.java

 

package ex08Class;

//과일 판매를 추상화한 클래스
class FruitSeller3{
	int numOfApple; //판매자의 사과 보유 갯수
	int myMoney; //판매 수익
	final int APPLE_PRICE; //사과의 단가
	
	/*
	 상수는 값이 변경이 불가능하고, 단 한번만 초기화되기 때문에
	 일반적인 맴버메소드에서는 초기화 할 수 없다.
	 하지만 생성자 메소드에서는 초기화가 가능하다.
	 마음대로 호출할 수 없고, 객체생성시 단 한번만 호출되는 
	 특성이 동일하기 때문에 한번 이상 초기화 하지 않음이 보장되기
	 때문이다.
	 */
	public FruitSeller3(int money, int appleNum, int price) {
		myMoney = money;
		numOfApple = appleNum;
		APPLE_PRICE = price;
	}

	public int saleApple(int money) {
		int num = money / APPLE_PRICE;
		numOfApple -= num;
		myMoney += money;
		return num;
	}
	//판매자의 현재상태를 출력하는 맴버메소드
	public void showSaleResult() {
		System.out.println("[판매자] 남은 사과 개수 : " + numOfApple);
		System.out.println("[판매자] 판매수익 : " + myMoney);
	}
}




//구매자를 표현한 클래스
class FruitBuyer3{
	int myMoney = 5000;//보유 금액
	int numOfApple = 0;//구매한 사고의 갯수
	
	public void initMembers(int _myMoney, int _numOfApple) {
		myMoney = _myMoney;
		numOfApple = _numOfApple;
		
	}
	public void buyApple(FruitSeller3 seller, int money) {
		numOfApple += seller.saleApple(money);
		myMoney -= money;
	}
	
	public void showBuyResult() {
		System.out.println("[구매자] 연재잔액 : " + myMoney);
		System.out.println("[구매자] 사과갯수 : " + numOfApple);
	}
}


public class E06FruitSalesMain3 {
	
	public static void main(String[] args) {
		
		/*
		 초기화 메소드를 정의하였으므로, 각각 성격이 다른 객체들을 생성할 수 있다. 
		 */
		//판매자 1 : 보유갯수가 100개 단가 1000원
		FruitSeller3 seller1 = new FruitSeller3(0, 100, 1000);
		
		//판매자 2 : 보유갯수 80개 단가 500원
		FruitSeller3 seller2 = new FruitSeller3(0, 80, 500);
		
		FruitBuyer3 buyer = new FruitBuyer3();
		buyer.initMembers(10000, 0);
		
		
		System.out.println("구매행위가 일어나기 전의 상태");
		seller1.showSaleResult();
		seller2.showSaleResult();
		buyer.showBuyResult();
		
		//판매자1, 판매자2에게 각각 5000원을 지불하고 구매
		buyer.buyApple(seller1, 5000);
		buyer.buyApple(seller2, 5000);
		
		
		System.out.println("구매행위가 일어난 후의 상태");
		seller1.showSaleResult();
		seller2.showSaleResult();
		buyer.showBuyResult();
	}

}

 

생성자를 통해 좀 더 깔끔하고 좋은 코드가 되었습니다. 다음 번엔 클래스로 예제를 풀어봅시다.

 

 

결과 값

E06FruitSalesMain1.java

 

E06FruitSalesMain2.java

E06FruitSalesMain3.java