본문 바로가기

JAVA

[JAVA] 카드 사용 프로그램 (Equals() 메소드, instanceof 연산자)

반응형
<프로그램 설계도> 
class Card
 String name // 카드사용자
 int money // 현재까지 사용한 금액 (처음에는0) 
 boolean flag // 제한금액 여부 (F면 제한금액 없음)  
 int limit // 제한금액 (T면 제한금액 있음) 
 void pay(int money) // money만큼 결제
 void alert() // "제한금액을 초과하여 사용할수없습니다!"라는 경고문구를 출력

--생성자--(2가지)
Card("홍길동") -> 제한금액 없음
Card("홍길동",10000) -> 제한금액 있음(10000원으로 설정됨)
출력시 : ㅇㅇ님 현재까지 사용한 금액은 ㅁㅁ원입니다. 제한금액 O: xxx원
                                                                                       제한금액 X

class CreditCard
int cnt // 제한금액을 초과하는 결제 횟수를 카운팅
void alert() "제한금액을 초과하여 사용할수없습니다! [총 N회 경고]"라는 경고문구를 출력
CreditCard("홍길동",10000) -> 제한금액 있음(10000원으로 설정됨)
출력시 : ㅇㅇ님 현재까지 사용한 금액은 ㅁㅁ원입니다. 제한금액 O: xxx원

class BusCard
int age // 카드사용자의 나이
int check() // 카드사용자의 나이가 ~12 0원 / 13~19 1000원 / 20~65 2000원 / 66~ 0원을 반환
void pay() // 카드사용자의 나이에 맞게 결제 (부모와 인자<자료형타입>가 달라서 오버라이딩이 아니고 오버로딩) BusCard("홍길동",21) -> 나이 21세.제한금액 없음 BusCard("홍길동",21,10000)
-> 나이 21세.제한금액 있음(10000원으로 설정됨)
단, 나이는 0~200까지만 유효하게 설정되며 0미만이거나 200초과의 값에 대해서는 20으로 설정됨
출력시 : ㅇㅇ님(21세) 현재까지 사용한 금액은 ㅁㅁ원입니다. 제한금액 O: xxx원
                                                                                                   제한금액 X
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
class Card{
    String name;// 카드 사용자
    int money;// 현재까지 사용한 금액
    boolean flag; // 제한금액
    int limit;// 제한금액 여부
    void pay(int money) {//결재금액
        if(this.flag && this.money+money>this.limit) { 
            // 만약에 제한금액이 있다면 현재까지 사용한금액+결재금액 > 제한 
            this.alert(); //경고문구 출력 
            return;
        }
        this.money+=money; // 제한금액이 없는경우 
        System.out.println(this.name+"님 결제완료. 누적사용금액: "+this.money);
    }
    void alert() {
        System.out.println(this.name+"님, 제한금액을 초과하여 사용할수없습니다!");
    }
    Card(String name){
        this(name,0);
        this.flag=false;
    }
    Card(String name,int limit){
        this.name=name;
        this.flag=true;
        this.money=0;
        this.limit=limit;
    }
    @Override
    public String toString() {
        String msg=this.name+"님 현재까지 사용한 금액은 ";
        msg+=this.money+"원입니다. 제한금액 ";
        if(flag) {
            msg+="O: "+this.limit+"원";
        }
        else {
            msg+="X";
        }
        return msg;
    }
    @Override
    public boolean equals(Object obj) { 
        
        if (obj instanceof Card) {//비교대상 너, Card가 될수있는 객체니? 
            // instanceof 객체 타입을 확인하는데 사용하는 연산자 
            // 객체 instanceof 클래스
            // == 객체가 클래스가 될수있니? 
            Card card=(Card)obj; // 타입 캐스팅 (다운 캐스팅=명시적형변환)
            if(this.name.equals(card.name)) { //내이름과 오브젝트의 이름이 같니? 
                return true;
            }
        }//    혹시 card가 될수없다면 넌 무조건 false
        return false;
    }
}
class CreditCard extends Card{
    int cnt;
    @Override
    void alert() {
        super.alert();
        this.cnt++;
        System.out.println("[총 "+this.cnt+"회 경고]");
    }
    CreditCard(String name,int limit){
        super(name,limit);
        // 부모클래스에게 기본생성자가 없으니까,
        // 가지고있는 생성자를 호출하여 사용할예정!
        this.cnt=0;
    }
}
class BusCard extends Card{
    int age;
    int check() {
        int fare=0;
        if(12<this.age&&this.age<20) {
            fare=1000;
        }
        else if(19<this.age&&this.age<66) {
            fare=2000;
        }
        return fare;
    }
    // 오버라이딩: 상속관계 / 메서드 시그니쳐가 같을때 / 함수 재정의
    // 오버로딩: 상속관계xxx / 메서드 시그니쳐가 다를때 / 함수명 중복정의 허용
    void pay() { // 오버로딩
        this.pay(this.check());
    }
    BusCard(String name,int age){
        this(name,age,0);
        this.flag=false;
    }
    BusCard(String name,int age,int limit){
        super(name,limit);
 
        if(age<0||200<age) {
            age=20;
        }
        this.age=age;
    }
}
public class Test01 {
 
    public static void main(String[] args) {      
        Card c3=new Card("아무무");
        Card c1=new Card("아무무");
 
        // == : 연산자 -> 원시타입에 활용
        // .equals() : Object가 제공하는 메서드
        //             -> 객체가 실제로 저장된 주소값을 비교하는 로직 
->마음에 안들어서 오버라이딩해서 함수 재정의
        if(c1.equals(c3)) {
            System.out.println("같다!");
        }
        else {
            System.out.println("다르다!");
        }
        System.out.println();
 
        Card c2=new Card("아리",5000);
        c1.pay(100000);
        c2.pay(3000);
        c2.pay(4000);
        System.out.println(c1);
        System.out.println(c2);
 
        System.out.println();
 
        CreditCard cc=new CreditCard("티모",2000);
        cc.pay(1999);
        cc.pay(2);
        System.out.println(cc);
 
        System.out.println();
 
        BusCard bc1=new BusCard("나르",13,500);
        BusCard bc2=new BusCard("가렌",2500);
        bc1.pay();
        bc2.pay();
        System.out.println(bc1);
        System.out.println(bc2);
    }
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
    public boolean equals(Object obj) { 
        
        if (obj instanceof Card) {//비교대상 너, Card가 될수있는 객체니? 
            // instanceof 객체 타입을 확인하는데 사용하는 연산자 
            // 객체 instanceof 클래스
            // == 객체가 클래스가 될수있니? 
            Card card=(Card)obj; // 타입 캐스팅 (다운 캐스팅=명시적형변환)
            if(this.name.equals(card.name)) { //내이름과 오브젝트의 이름이 같니? 
                return true;
            }
        }//    혹시 card가 될수없다면 넌 무조건 false
        return false;
    }
}
cs

instanceof 연산자 

  • instanceof는 객체 타입을 확인하는 연산자이다.
  • 형변환 가능여부를 확인하며 true / false 로 결과를 반환한다.
  • 주로 상속 관계에서 부모객체인지 자식객체인지 확인하는데 사용된다.
  • instanceof의 기본 사용방법은 "객체 instanceof 클래스" 를 선언함으로써 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
    public boolean equals(Object obj) { 
        
        if (obj instanceof Card) {//비교대상 너, Card가 될수있는 객체니? 
            // instanceof 객체 타입을 확인하는데 사용하는 연산자 
            // 객체 instanceof 클래스
            // == 객체가 클래스가 될수있니? 
            Card card=(Card)obj; // 타입 캐스팅 (다운 캐스팅=명시적형변환)
            if(this.name.equals(card.name)) { //내이름과 오브젝트의 이름이 같니? 
                return true;
            }
        }//    혹시 card가 될수없다면 넌 무조건 false
        return false;
    }
}
cs

equals를 먼저 Object 타입으로 매개변수를 받는다.

들어온 매개변수는 Object 타입이기 때문에 Card클래스 내의 필드를 사용할 수 없다.

그래서 Card로 형변환 (downcasting) 을 해줘야한다.

코드와 같이 (Card)obj와 같이 downcasting하면 Crad의 필드를 사용할수있다.

그런 뒤에 가독성을 위해 this를 붙여서 this의 name과  card.name을 비교해서 return 하면 된다.

반응형