JAVA/코드

TEAM과제 -삼중상속

record2080 2025. 1. 18. 23:52
package test;

import java.util.Random;
import java.util.Scanner;



abstract class Animal {   //만든 클래스 중 제일 상위 추상 클래스
   private String name;   //멤버변수 private 선언
   private String type;   
   private String habitat;
   private String food;
   private int hp;
   private int cnt;
   static Random rand=new Random();   //모두 가져다 쓸 수 있도록 Random, Scanner 계속 사용할거라 객체와 무관한 static으로 멤버변수화
   static Scanner sc=new Scanner(System.in);


   Animal(String name, String type, String habitat, String food) { //객체 초기화 위해 생성자
      this.name = name;                     //체력 빼고 입력 받을 것
      this.type = type;
      this.habitat = habitat;
      this.food = food;
      this.hp = 10;   //체력만 10으로 고정

   }
   abstract void eat(); //추상 메서드 구현X

   @Override
   public String toString() {
      if(this.hp<=0) {   //만약 체력이 0이하이면 [기절] 출력
         return "[기절] "+this.name;
      }
      return "Animal [name=" + name + ", type=" + type + ", habitat=" + habitat + ", food=" + food + ", hp=" + hp
            + "]";   //체력이 1이상일경우 전체 출력
   }
   public String getName() {   //getter/setter
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getType() {
      return type;
   }
   public void setType(String type) {
      this.type = type;
   }
   public String getHabitat() {
      return habitat;
   }
   public void setHabitat(String habitat) {
      this.habitat = habitat;
   }
   public String getFood() {
      return food;
   }
   public void setFood(String food) {
      this.food = food;
   }
   public int getHp() {
      return hp;
   }
   public void setHp(int hp) {
      this.hp = hp;
   }
   public int getCnt() {
      return cnt;
   }
   public void setCnt(int cnt) {
      this.cnt = cnt;
   }

}

abstract class Fish extends Animal{   //Animal 상속 받는 추상 클래스
   private int finCnt; // 멤버변수 private로 선언
   private int depth;

   Fish(String name, String food, int depth){ //생성자
      super(name,"어류","물",food);
      this.finCnt=6; // 기본 지느러미 개수 6개로 초기화
      this.depth=depth;

   }

   Fish(String name,String food,int finCnt, int depth){ //생성자
      super(name,"어류","물",food);
      this.finCnt=finCnt;
      this.depth=depth;

   }

   abstract void swim();//추상 메서드 구현X
   abstract void eat();//추상 메서드 구현X

   public int getFinCnt() {
      return finCnt;
   }

   public void setFinCnt(int finCnt) {
      this.finCnt = finCnt;
   }

   public int getDepth() {
      return depth;
   }

   public void setDepth(int depth) {
      this.depth = depth;
   }


}
abstract class Bird extends Animal{//Animal 상속 받는 추상 클래스

   private boolean fly; // 멤버변수 private로 선언하여 외부에서 값을 맘대로 바꿀 수 없도록 함.
                  // 날 수 있는지 양자택일 여부를 boolean으로 선언 
   private int flyDistance;
   Bird(String name,String food,boolean fly){ //생성자
      super(name,"조류","하늘",food);
      this.fly=fly; 
      this.flyDistance=0; // 입력 없을 시 기본 비행거리 0으로 초기화 
   }
   Bird(String name,String food,boolean fly,int flyDistance){//생성자
      super(name,"조류","하늘",food);
      this.fly=fly;
      this.flyDistance=flyDistance;
   }
   abstract void fly(); // 추상 메서드. 구현 x
   abstract void eat(); // 추상 메서드. 구현 x

   public boolean isFly() {
      return fly;
   }

   public void setFly(boolean fly) {
      this.fly = fly;
   }

   public int getFlyDistance() {
      return flyDistance;
   }

   public void setFlyDistance(int flyDistance) {
      this.flyDistance = flyDistance;
   }

}
class Shark extends Fish implements CreatureAct{ //Fish 상속 받고 CreatureAct 인터페이스 가져옴
   Shark(){
      super("상어","물고기",1000);

   }
   void bite() {
      char ans;
      while(true) {
         System.out.println("공격하시겠습니까?>>Y/N"); //유효성 검사
         System.out.print("대답 입력>> ");
         ans=sc.next().charAt(0); // 사용자에게 입력받은 문자열 첫 글자가 Y라면 
         ans = Character.toUpperCase(ans); // 소문자일 경우(y) 대문자로 변환하여 y, Y 둘 다 가능하게 
         if(ans!='Y'&& ans!='N') { // Y나 N이 아니라면
            System.out.println("정확히 입력해주세요!"); // 다시 입력하도록
            continue; //유효성 검사
         }
         else {
            break;
         }
      }
      if(ans=='Y') {     
         if(rand.nextInt()<7) { // 70% 확률 
            setHp(getHp()+5);   //private으로 선언한 변수를 getter로 가져오고 setter로 값 재설정
            System.out.println("사냥을 성공했어요! 밥을 먹을 수 있습니다");
         }      
         else {
            setHp(getHp()-3); // getter로 값을 가져온 후 3 빼고 setter로 재설정
            System.out.println("먹이가 도망갔습니다.오늘은 굶어야해요..");
         }
      }
      System.out.println("사냥 종료! 현재 "+getName()+" 체력: " + getHp());    //getter로 멤버변수 가져옴
   }


   @Override // 가독성 위해 추가
   void swim() { // 오버라이딩
      System.out.println("상어가 빠른 속도로 헤엄칩니다!");

   }

   @Override // 가독성 위해 추가
   void eat() { // 오버라이딩
      setHp(getHp()+5); // getter/setter로 재설정
      System.out.println(getName()+"이(가) "+getFood()+"을(를) 먹습니다!"); // 이름과 먹이를 getter로 불러와서 출력
      System.out.println("현재 체력: "+getHp()); // getter 사용

   }
   public void makeEgg(){ // CreatureAct 인터페이스 구현
      System.out.println(getName()+"이(가) 알을 낳습니다"); // getter
   }




}
class Salmon extends Fish implements CreatureAct{//Fish 상속 받고 CreatureAct 인터페이스 가져옴
   Salmon(){
      super("연어","곤충",20);
   }
   int goToRiver(Animal[] datas,int cnt) {
      char input;
      while(true) {
         System.out.print("강으로 올라가시겠습니까? Y/N >>");//유효성 검사
         input=sc.next().charAt(0); // 사용자에게 입력받은 문자열의 첫 글자를 판단
         input = Character.toUpperCase(input); // 만약 소문자일 경우 대문자로 변환
         if(input=='Y' || input=='N') { // Y나 N이면 반복문 탈출
            break;
         }
         System.out.println("Y/N 을 입력해주세요");
      }
      if(input=='Y') {
         if(rand.nextInt(10)<4) { // 40% 확률
            setHp(0); // 곰을 만나면 체력을 0으로 설정
            System.out.println("곰을 만나서 체력이 0이 되었습니다..휴식이 필요해요...");
         }
         else {
            boolean flag=false; 
            setHp(getHp()+3); // 체력 받아와서 +3하고 setter로 재설정
            System.out.println("여행 완료! 현재 연어 체력: " + getHp());  
            for(int i=0;i<datas.length;i++) {   //유효성 검사
               if(datas[i]==null) { // 배열의 요소가 null일 때 (nullpointerexception 에러 방지)
                  datas[i]=new Salmon(); // 새로운 연어를 도감에 추가
                  System.out.println("친구를 만났습니다. 새로운 연어가 등록되었습니다!");
                  cnt++; // 배열 요소 개수 증가
                  flag=true;
                  break;
               }
            }
            if(!flag) { // 도감이 가득 찬 경우(배열에 빈 공간 x)
               System.out.println("도감이 꽉 차서 친구를 추가할 수 없어요ㅠ");
            }
         }
      }
      return cnt; // cnt를 main에서 생성해서 요소로 받아왔기 때문에 반환하지 않으면 main의 값이 바뀌지 않기 때문에 반환함
               
   }
   @Override
   void swim() {
      System.out.println("연어가 여유롭게 헤엄칩니다!");

   }

   @Override
   void eat() {
      setHp(getHp()+5); // getter,setter
      System.out.println(getName()+"이(가) "+getFood()+"을(를) 먹습니다!");
      System.out.println("현재 체력: "+getHp());
   }
   @Override
   public void makeEgg() { //CreatureAct 인터페이스 구현
      System.out.println(getName()+"이(가) 알을 낳습니다");

   }

}
class Goofy extends Fish{//Fish 상속 받고 CreatureAct 인터페이스 가져오지 않음
   // 알을 낳지 않는다고 동물이 아니지 않기 때문에
   Goofy(){
      super("구피","플랑크톤",1);
   }

   void makeFriend() {
      char ans;
      while(true) {
         System.out.println("친구를 사귀시겠습니까?>>Y/N"); 
         System.out.print("대답 입력>> ");
         ans=sc.next().charAt(0); // 문자열 첫번째 확인
         ans = Character.toUpperCase(ans); // 소문자 대문자로
         if(ans!='Y'&& ans!='N') {   //유효성 검사
            System.out.println("정확히 입력해주세요!");
            continue; 
         }
         else {
            break;
         }
      }
      if(ans=='Y') {     
         if(rand.nextInt()<7) { // 70% 확률 
            setHp(getHp()+5); // getter,setter
            System.out.println("친구를 사겼습니다!");
         }      
         else {
            setHp(getHp()-3);// getter,setter
            System.out.println("친구 만들기 실패..");
         }
      }
      System.out.println(getName()+" 체력: " + getHp()); 
   }
   @Override
   void swim() { // 오버라이딩
      System.out.println("구피가 무리지어 헤엄칩니다!");

   }

   @Override
   void eat() { // 오버라이딩
      setHp(getHp()+5);// getter,setter
      System.out.println(getName()+"이(가) "+getFood()+"을(를) 먹습니다!");
      System.out.println("현재 체력: "+getHp());

   }
}
class Penguin extends Bird implements CreatureAct{//Bird 상속 받고 CreatureAct 인터페이스 가져옴
   Penguin(){ 
      super("펭귄","작은 물고기",false,0);
   }
   void gatheringPenguin() {
      int rand=new Random().nextInt(100)+1;   // 100마리
      System.out.println("과연 펭귄은 몇마리가 모였을까요0^0?");
      System.out.println(rand+"마리가 모였네요!");
      if(rand>=10) {  // 10마리 이상 모이면
         setHp(getHp()+5); // 체력 5 추가
         System.out.println("결과: 따뜻하네요..ㅎ");
      }
      else {
         setHp(getHp()-3); // 체력 3 감소
         System.out.println("결과: 혹한을 견디지 못했습니다." );
      }
      System.out.println("체력: "+getHp());
   }
   @Override
   void fly() { // 오버라이딩
      System.out.println(getName()+": 푸드덕.....");

   }

   @Override
   void eat() { // 오버라이딩
      setHp(getHp()+5);
      System.out.println(getName()+"이(가) "+getFood()+"을(를) 먹습니다!");
      System.out.println("현재 체력: "+getHp());

   }
   @Override
   public void makeEgg() { //CreatureAct 인터페이스 구현
      System.out.println(getName()+"이(가) 알을 낳습니다");

   }
}
class Parrot extends Bird implements CreatureAct{//Bird 상속 받고 CreatureAct 인터페이스 가져옴
   Parrot(){
      super("앵무새","씨앗",true,50);
   }
   void micmick() {
      getHp();
      System.out.print("훈련시킬 단어를 입력하세요! >> ");
      String word = sc.next(); // 사용자에게 문자열 입력 받음
      System.out.println("훈련 중...");
      System.out.println("훈련 시작! 현재 앵무새 체력: " + getHp() ); 

      for (int i = 0; i < 3; i++) {
         int SuccessRate;

         // 각 시도에 따른 성공 확률 설정
         if (i == 0) SuccessRate = 50; // 첫 번째 시도: 50%
         else if (i == 1) SuccessRate = 70; // 두 번째 시도: 70%
         else SuccessRate = 100; // 세 번째 시도: 100%

         // if문으로 for문 돌 때 확률 미리 설정
         System.out.println((i + 1) + "번째 시도 중... (성공 확률: " + SuccessRate + "%)");

         // 랜덤 확률로 훈련 반복
         // 위에서 설정한 확률에 맞춰 반복문 실행
         if (rand.nextInt(100) < SuccessRate) {
            System.out.println("훈련 성공!");
            System.out.println("앵무새 : " + word);
            setHp(getHp() + 5);
            break; // 성공 시 반복 종료
         } else {
            setHp(getHp() - 3);
            System.out.println("훈련 실패... 다시 시도합니다.");

            System.out.println("훈련 실패 후 현재 앵무새 체력: " +getHp()); 
         }
      }
      System.out.println("훈련 종료! 현재 앵무새 체력: " + getHp()); 
   }
   @Override
   void fly() {
      System.out.println("앵무새가 하늘을 훨훨 날았습니다!");

   }

   @Override
   void eat() {
      setHp(getHp()+5);
      System.out.println(getName()+"이(가) "+getFood()+"을(를) 먹습니다!");
      System.out.println("현재 체력: "+getHp());


   }
   @Override
   public void makeEgg() { //Creature 인터페이스 구현
      System.out.println(getName()+"이(가) 알을 낳습니다");

   }
}

public class AnimalProject02 {

   public static void main(String[] args) {
      Animal[] datas=new Animal[6];   //main 클래스에서 배열 생성
      datas[0]=new Shark();
      datas[1]=new Salmon();
      datas[2]=new Goofy();
      datas[3]=new Penguin();
      datas[4]=new Parrot();
      int cnt=5;   //배열에 저장된 개수

      while(true) {   //메뉴 선택
         System.out.println("0. 종료");
         System.out.println("1. 동물 전체 출력");
         System.out.println("2. 종류에 따른 행동하기");
         System.out.println("3. 개별 행동하기");
         System.out.println("4. 밥주기");
         System.out.print("메뉴를 입력하세요>>");
         Scanner sc=new Scanner(System.in);
         int menu=sc.nextInt();

         if(menu==0) {
            break;
         }
         else if(menu==1) {   //전체 출력
            for(int i=0;i<datas.length;i++) {
               if(datas[i]==null) { // 배열에 요소가 없으면
                  System.out.println("비어있음"); // 비어있음 출력
               }
               else {
                  System.out.println(datas[i]+" "); //toString 메서드 사용
               }
            }
         }
         else if(menu==2) {   //종류를 선택해서
            int input;      //종류만이 할 수 있는 메서드 호출
            while(true) {
               System.out.println("동물 종류를 선택하세요>>");
               System.out.print("1.어류 2.조류 >> " );
               input = sc.nextInt();
               if(input == 1 || input == 2) {
                  break;
               }
               System.out.println("올바른 번호를 입력해주세요");
            }

            if(input == 1) {   //어류 메서드 수행
               for(int i = 0; i < datas.length; i++) {
                  if(datas[i] != null && datas[i].getType().equals("어류")) { // getType으로 받아온 종류가 어류라면 swim 메서드 호출
                     Fish fish=(Fish)datas[i]; //Animal타입의 배열을  
                     //Fish 타입으로 다운캐스팅
                     fish.swim();   //다운캐스팅 해서 메서드 호출
                  } 
               }
            }
            else {
               for(int i = 0; i < datas.length; i++) {   // getType으로 받아온 종류가 조류라면 조류가 가진 fly 메서드 호출
                  if(datas[i] != null && datas[i].getType().equals("조류")) {
                     Bird Bird=(Bird)datas[i]; //다운캐스팅
                     Bird.fly();
                  }
               }
            } 
         }

         else if(menu==3) {   //동물 선택해서 각각 가지고 있는 메서드 호출
            while(true) {
               System.out.println("개별 행동하기! 동물을 선택하세요");
               System.out.println("1. 상어 2.연어 3.구피 4.펭귄 5.앵무새");   //행동할 동물 선택
               int input;
               input=sc.nextInt();
               if(input<1 || 5<input) {   //UI/UX
                  System.out.println("올바르게 입력하세요");
                  continue;
               }

               if(datas[input-1].getHp()==0) {   //유효성 검사
                  System.out.println("체력이 0이에요ㅠ");
                  break;
               }

               else if(input==1) {      //배열의 요소들 다운캐스팅해서 
                  Shark shark=(Shark)datas[0]; //메서드 호출
                  shark.bite();
                  break;
               }
               else if(input==2) {
                  Salmon salmon=(Salmon)datas[1];
                  cnt=salmon.goToRiver(datas,cnt);
                  break;
               }
               else if(input==3) {
                  Goofy goofy=(Goofy)datas[2];
                  goofy.makeFriend();
                  break;
               }
               else if(input==4) {
                  Penguin penguin=(Penguin)datas[3];
                  penguin.gatheringPenguin();
                  break;
               }
               else if(input==5) {
                  Parrot parrot=(Parrot)datas[4];
                  parrot.micmick();
                  break;
               }
               else {
                  System.out.println("올바른 숫자를 입력해주세요");
               }
            }
         }
         else if(menu==4) {   //동물을 선택해서 먹기 메서드 호출
            while(true) {
               System.out.println("누구에게 밥을 줄까요?");
               System.out.print("1. 상어 2.연어 3.구피 4.펭귄 5.앵무새>>");
               int input=sc.nextInt();
               if(input==1) {
                  Shark shark=(Shark)datas[input-1];
                  shark.eat();
                  break;
               }
               else if(input==2) {
                  for(int i=0;i<cnt;i++) {
                     if(datas[i].getName().equals("연어")) { // 문자열 비교. getName으로 받아온 문자열이 연어와 같으면
                        System.out.println(i+1+"번"+datas[i].getName());  // 몇번연어인지 출력
                     }
                  }
                  int num;
                  while(true) {
                     System.out.print("몇 번에게 줄까요?>>");   //유효성 검사
                     num=sc.nextInt();
                     if(0<num && num<=datas.length) {
                        break;
                     }
                     System.out.println("올바른 번호를 입력해주세요");
                  }
                  datas[num-1].eat();
                  break;

               }
               else if(input==3) {
                  Goofy goofy=(Goofy)datas[input-1];
                  goofy.eat();
                  break;
               }
               else if(input==4) {
                  Penguin penguin=(Penguin)datas[input-1];
                  penguin.eat();
                  break;
               }
               else if(input==5) {
                  Parrot parrot=(Parrot)datas[input-1];
                  parrot.eat();
                  break;
               }
               else {
                  System.out.println("올바른 번호를 입력해주세요");
               }
            }
         }
      }
   }
}