0908 | Do it! 자바 프로그래밍 입문 :: 6장 '클래스와 객체2' 연습문제
Q1. 클래스 내부에서 자신의 주소를 가르키는 예약어를 this 라고 합니다.
Q2. 클래스에 여러 생성자가 오버로드되어 있을 경우에 하나의 생성자에서 다른 생성자를 호출할 때 this를 사용합니다.
Q3. 클래스 내부에 선언하는 static 변수는 생성되는 인스턴스마다 만들어지는 것이 아닌 여러 인스턴스가 공유하는 변수입니다. 따라서 클래스에 기반한 유일하는 의미로 클래스 변수라고도 합니다.
Q4. 지역 변수는 함수나 메서드 내부에서만 사용할 수 있고 스택 메모리에 생성됩니다. 멤버 변수 중 static 예약어를 사용하는 static은 데이터 영역에 생성됩니다.
Q5. 아침 출근길에 김 씨는 4000원을 내고 별다방에서 아메리카노를 사 마셨습니다.
이 씨는 콩다방에서 4500원을 내고 라테를 사 마셨습니다. 객체간 협력을 참고하여 이 과정을 객체지향으로 프로그래밍해보세요.
* 가격과 메뉴이름을 매칭시키려니 이걸 어떻게 연결해야할지 잘 모르겠어서 일단은 아메리카노 이름은 사람 속성 안에 String으로 설정하고 가격도 고정값으로만 넣어두었다. 즉 스벅은 아메리카노 4000원 ,커피빈은 라떼 4500원 단일 메뉴만 팔때, 두 사람이 다른 메뉴 다른 매장을 가지 않을때만 가능한 상황...
public class Customer {
public String name;
public int money;
private String coffee; // public으로 선언하니 에러가 나고 private로 하라고 뜨던데 이유를 모르겠다.
public Customer(String name, int money,String coffee) {
this.name=name;
this.money=money;
this.coffee = coffee;
}
public void visitStar(Star star) {
star.take(4000);
this.money-=4000;
}
public void visitBean(Bean bean) {
bean.take(4500);
this.money-=4500;
}
public void showInfo() {
System.out.println(coffee+ "를 주문한 " + name+"님의 남은 돈은 "+ money + "입니다.");
}
}
public class Star {
String coffeeName;
int money=150000;
int customerCount=30;
String cafeName;
public Star(String cafeName) {
this.cafeName=cafeName;
}
public void take(int money) {
this.money+=money;
customerCount++;
}
public void showInfo() {
System.out.println("카페"+cafeName+"의 손님수는 "+customerCount+"명이고 수익은 "+money+"입니다.");
}
}
public class Bean {
String coffeeName;
int money=320000;
int customerCount=40;
String cafeName;
public Bean(String cafeName) {
this.cafeName=cafeName;
}
public void take(int money) {
this.money+=money;
customerCount++;
}
public void showInfo() {
System.out.println("카페"+cafeName+"의 손님수는 "+customerCount+"명이고 수익은 "+money+"입니다.");
}
}
public class CustomerTest {
public static void main(String[] args) {
Customer customerLee = new Customer("이은서", 50000, "아메리카노");
Star star = new Star("스타벅스");
customerLee.visitStar(star);
customerLee.showInfo();
star.showInfo();
Customer customerKim = new Customer("김윤주", 48000, "라떼");
Bean bean = new Bean("커피빈");
customerKim.visitBean(bean);
customerKim.showInfo();
bean.showInfo();
}
}
답안지를 보니 menu클래스에 public static final int americano = 4000;으로 각 카페당 두개씩 메뉴판을 만들어 놓았고 person의 buyCoffee에서 String message = sCoffee.brewing(4000); if(message != null) { 를, 각 카페 클래스에도 if(money == Menu.BEANAMERICANO) return "콩 다방 아메리카노를 구입했습니다"; 이런 식이 들어가있는데 관계가 이해가 안가서 따라하지도 못하곘다 언젠가 이해하고 수정할 날이 오겠지.
나의 최대치는 아직 여기까지...😂
Q6. 카드 회사에서 카드를 발급할 때마다 카드 고유 번호를 부여해줍니다. 카드가 생성될 때마다 카드번호가 자동으로 증가할 수 있도록 카드클래스를 만들고 생성해 보세요.
* card class
public class Card {
private static int serialNumber=1001000;
public int cardNumber;
String cardName;
public Card() {
serialNumber++;
cardNumber=serialNumber;
}
public String getcardName() {
return cardName;
}
public void setcardName(String name) {
cardName= name;
}
public static int getSerialNumber() {
return serialNumber;
}
public static void setSerialNumber(int number) {
Card.serialNumber= serialNumber;
}
}
* card Test class
public class CardTest {
public static void main(String[] args) {
Card card1 = new Card();
card1.setcardName("삼성올인원");
System.out.println(card1.getcardName()+"의 카드번호는 " + card1.cardNumber);
Card card2 = new Card();
card2.setcardName("삼성투게더");
System.out.println(card2.getcardName()+"의 카드번호는 " + card2.cardNumber);
Card card3 = new Card();
card3.setcardName("삼성패밀리");
System.out.println(card3.getcardName()+"의 카드번호는 " + card3.cardNumber);
}
}
Q7. Q6에 구현한 내용에 카드회사클래스 CardCompany를 싱글톤패턴을 사용하여 구현해 보세요.
*card company class
public class CardCompany {
private CardCompany() {}
private static CardCompany instance = new CardCompany();
public static CardCompany getInstance() {
if(instance==null);
instance = new CardCompany();
return instance;
}
public Card createCard() {
Card card = new Card();
return card;
}
}
* card class
public class Card {
private static int serialNumber=1001000;
private int cardNumber; // 여기서 static을 사용하면 아래의 get set 카드넘버마다 다 static으로 지정해줘야함
public String cardName;
public Card() {
serialNumber++;
cardNumber=serialNumber;
}
public int getCardNumber() {
return cardNumber;
}
public void setCardNumber(int number) {
this.cardNumber= number; // static때문에 Card.cardNumber로 작동하다가 static 지우니 this로 가능해짐.
}
public String getCardName() { // 나는 뒤에서 카드이름을 지정하고 싶어서 추가했다.
return cardName;
}
public void setCardName(String name) {
this.cardName=name;
}
}
* card company test class
public class CardTest {
public static void main(String[] args) {
CardCompany company = CardCompany.getInstance();
Card card1 = company.createCard();
Card card2 = company.createCard();
card1.setCardName("가족카드"); //결과값에 카드이름을 지정하려고 설정추가해줌!
card2.setCardName("모아카드");
System.out.println(card1.getCardName()+"의 카드 번호는 "+ card1.getCardNumber());
System.out.println(card2.getCardName()+"의 카드 번호는 "+ card2.getCardNumber());
}
}
✔ 카드 이름 세팅해넣으려고 이것저것 생각을 많이 했는데 createCard()는 정말로 카드 생성에 해당하므로,카드클래스에서 속성을 추가하고 세팅해주면 되는거였다! 자꾸 String 주소값이나 null값이 나와서 헤맸는데 원하던 모양대로 나오니까 세상 기쁘다!!!!!!! ✨😭
✔ 이렇게 연속으로 문제를 풀어보니 그냥 카드 생성자를 가지고 뉴 카드를 생성하는 것과, 싱글톤 패턴으로 상위에 카드 회사가 있을때 카드를 생성하는 것은 방법이 다르다는게 확 느껴진다.
전자는 카드속성을 지정해주고 new card() 생성자를 만들때마다 카드 이름 지정, 번호를 끌어온다면
후자는 카드회사의 속성으로 createCard를 넣어주고 카드 클래스에는 카드번호 증가값과 카드이름 지정할수 있도록 세팅, 마지막 테스트에서 createCard로 뉴 카드를 생성하게 되고 번호를 끌어오면 된다.
그냥 카드회사를 싱글톤패턴으로만 만들면 된다고 생각했는데 생각보다 여기저기 많이 고쳐야했다.
코드를 쓸땐 오픈북이긴 했지만 get,set 감도 잡혀가고 원하는 모양대로 끌어내는덴 성공해서 뿌듯하다!!!!!!!!!!