본문 바로가기
혼자서 개발새발

JAVA) 상속+추상클래스+다형성으로 다마고치를 만들어보자!

by 휴일이 2022. 10. 6.

 

어제 상속만으로 다마고치를 만들었는데

오늘은 상속+추상클래스+다형성(조상 참조변수로 자식 인스턴스 불러와서 조종 가능)으로

코드를 좀 더 예쁘게(?) 만들어보았다

 

 

 

 

조상 클래스(추상 클래스)

 

public abstract class MonVO { // 부모가 될 추상 클래스(설계도)

    // 자식들에게 공통적으로 들어가야할 값을 부여한다
    protected String mon; //몬스터 이름
    protected int level; //레벨
    protected int ex; //경험치
    protected int energy; //에너지


    public abstract void eat(); //먹기
    public abstract void play(); //놀기
    public abstract void levelUp(); //레벨업
    public abstract void sleep(); //자기
    public abstract void dead(); //죽음
    public abstract void info(); //정보창
    public abstract void workOut(); //운동

}

 

자식들에게 공통적으로 들어가야 할 변수와 메소드를 입력했다

추상 클래스와 메소드 앞에는 abstract 를 붙여준다(미완성)

 

 

 

자식 클래스(피카츄)

 

public class Picachoo extends MonVO {

    public Picachoo() {
        mon="피카츄";
        energy = 50;
    } //기본 생성자에 이름과 초기 에너지값 생성!

    @Override
    public void eat(){
        System.out.println("밥을 먹었습니다");
        energy+=20;
        ex++; //행동을 할 때마다 경험치에 +1 한다
        levelUp();
        info();
    }
    @Override
    public void play() {
        System.out.println("놀아주었습니다");
        energy-=15;
        ex++;
        dead(); //에너지가 깎이는 행동을 할 때마다,에너지가 0이 됐는지 확인하는 메소드
        levelUp();
        info();
    }
    @Override
    public void levelUp() {
        if(ex>3) { //ex가 3이 되면 레벨업을 한다
            System.out.println("레벨 업!!");
            level++;
            ex=0;
        }
    }
    @Override
    public void sleep() {
        System.out.println("잠을 잡니다");
        energy+=15;
        ex++;
        levelUp();
        info();
    }
    @Override
    public void dead() {
        if(energy<=0) { //에너지가 음수가 되면 죽는다 깨꼬닥 아니라면 계속 실행
            System.out.println("뒤졌음ㅋㅋ");
            System.exit(0);
        }
    }
    @Override
    public void info() { //캐릭터 정보창
        System.out.println(mon+"의 체력 "+energy+" 경험치 "+ex+" 레벨 "+level);
    }

    @Override
    public void workOut() {
        System.out.println("운동 합니다");
        energy-=15;
        ex++;
        dead();
        levelUp();
        info();
    }
}

 

피카츄의 이름, 에너지를 생성자로 초기화해준 후

조상 메소드에 구현부를 붙여주고

@Override를 붙여주었다^.^ (오버라이딩 했다는 뜻, 컴파일러에게 알려줍니다, 본인도 알기 쉬움)

 

 

 

 

서비스하는 클래스

 

import java.util.Scanner;

public class GameService {

    public GameService() {} //기본생성자
    Scanner sc = new Scanner(System.in); //얘 주소값을 안 넣어주면 NullPointException 뜸 ㅠㅠ
    MonVO m;


    public void menu(Scanner sc) { //메인메서드에 호출 할 메뉴 메서드
        System.out.println("캐릭터 선택");
        System.out.println("1.피카츄 2.꼬부기 3.이상해씨");

        int i = 0; //if문에 넣을 i값
        i = sc.nextInt();

        if(i==1) { //다형성 이용, 부모 참조변수에 자식 인스턴스를 넣었다
            MonVO p = new Picachoo();
            playGo(p);
        } else if(i==2) {
            MonVO g = new Ggobugi();
            playGo(g);
        } else if(i==3) {
            MonVO ih = new Isanghae();
            playGo(ih);
        }
    }

    public void playGo(MonVO m) { //객체를 입력받음,(부모 타입 객체를 입력받음)
        // 부모타입의 객체는 자식으로 형변환이 가능해서, 참조변수 타입은 부모지만 인스턴스는 자식

        int i=0;
        boolean flag=true;

        while (flag) { //flag가 true이면 계속 돌려주기
            System.out.println("1.밥주기 2.놀아주기 3.잠자기 4.운동하기 5.종료");
            i = sc.nextInt(); //i 값(메뉴 값)을 받아서 돌려준다
            switch (i) {
                case 1: //밥먹기
                    m.eat();
                    break;
                case 2: //놀아주기
                    m.play();
                    break;
                case 3: //잠자기
                    m.sleep();
                    break;
                case 4: //운동
                    m.workOut();
                    break;
                case 5: //종료
                    System.out.println("종료합니다");
                    flag=false;
                    break;

            }

        }

    }

}

 

Scanner sc; 만 선언했다가

NullPointException을 만나 상당히 애를 먹었다 ㅠㅠ

Scanner에 주소값을 안 줘서 스캐너가 동작을 안 했던 것...

객체를 불러올 때는 꼭 인스턴스 생성(주소값주기)를 잊지 말자 !!!

 

 

메인 클래스

import java.util.Scanner;

public class GameMain {
    public static void main(String[] args) {

        GameService g = new GameService();
        Scanner sc = new Scanner(System.in);

        g.menu(sc);

        sc.close();



    }
}

 

메인은 간단하게 호출만!!

 

 

 

결과값

그는 좋은 꼬부기였습니다..

 

 

 

 

 

 

다형성 이딴걸 왜 사용하나 했더니

추상 클래스에서는 유용하게 쓸 수 있을 거 같당 ㅎㅎ

오늘도 하나 배워갑니다~~~

728x90