본문 바로가기

개발자노트

클래스) 상속..오버라이딩,다운캐스팅 응용예제(카드사용)

다운캐스팅을 하는 이유 = 객체와 문자열을 비교하기 위해서.

package class01;

// 1. 요구사항(조건)을 파악
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) { // Object는 모든 클래스의 객체를 담아 둘 수 있다.
      if(obj instanceof Card) { // 가능한 이유 -> Object는 Card클래스의 부모이기 때문에, Object클래스의 obj객체를 가지고 있음
         // 객체 instanceof 클래스
         //  == 객체가 클래스가 될수있니?
    	 // intsance = 객체 , 인스턴스화, 객체화
         Card card=(Card)obj; // 캐스팅(다운 캐스팅) -> obj에는 .name의 멤버변수가 없기 때문에 그 값을 Card에서 가져오게 하려고
//Card를통해 card라는 객체를 생성=(Card형식으로 형변환)obj를  --> 명시적 형변환의 형태이다.!!(자료형을 맞춰주는 것 같은거)
         // Card에서만 할당 즉 다른 클래스에 대한건 x
         if(this.name.equals(card.name)) {
            return true;
         }
      }      
      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_answer {

   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);
   }

}