Loading...

JAVA / / 2022. 1. 17. 13:48

자바 18강. abstract

반응형

신입이 실수하지 않는 코드를 짜는 방법을 알아보자.

 

스타크래프트 게임을 만든다고 하고, 프로토스가 공격하는 코드를 짤 것이다.

신입에게 새로운 유닛을 만드는 일을 주기 위해

팀장이 코드를 짜줄 것이다.

 

새로운 유닛을 만들 때 메서드의 이름을 틀릴 수도 있고,

빠트리는 메서드가 있을 수도 있다.

 

이때는 실수한 신입의 잘못이 아니다.

메서드의 실수가 있어도 오류가 나지 않게 틀을 만들어준 팀장의 잘못이다!!

 

이를 방지하기 위해 abstract 추상 클래스를 사용할 것이다.

객체의 행위를 공통적으로 정의할 수 없을 때 사용하는 것이다.

 

클래스명 앞에 abstract를 붙이면 몸체(클래스 중괄호 내부)가 필요 없게 된다.

구체적인 행위는 자식마다 다 다르니까

구체적인 자식에게 구체적인 행위를 맡기는 것이다.(위임)

부모의 클래스가 실행될 것도 아니므로 구체적 실행은 자식이 해야 한다.

 

추상 클래스는 일반 메서드도 만들 수 있다.

일반 메서드는 모든 구체적인 자식들의 공통적인 내용을 만들 때 사용한다.

 

일반 클래스에는 추상 메서드를 가질 수 없다.

 

추상 메서드를 구체적으로 직접 구현해야

일반 클래스에서 사용이 가능하다.

 

자식 클래스에서 추상 메서드를 사용하지 않으면

자식 클래스명에 오류가 발생한다.

 

오류가 뜨는 빨간 줄에 커서를 찍은 후 Alt+Enter키를 눌러준다.

 

Alt + Enter : 오류가 났을 때 어떻게 해결하면 좋을지 알려주는 힌트(매직키)

Add unimplemented methods

구현하지 않은 메서드를 자동으로 만들어주겠다는 버튼을 클릭해준다.

 

그러면 자동으로 메서드들이 생성되어 내부를 변경할 수 있게

틀이 자동 생성된다.

 

이때 메서드 이름을 자기 마음대로 바꾸면 오류가 발생하게 된다.

 

메서드 이름도 안 바뀔 거고, 빼먹는 메서드도 없을 것이다.

 

-> 실수하지 않게 강제성 부여

 

자바에서 추상 메서드는 왜 나왔을까?

 

어차피 부모 클래스는 통로로 쓸건데 구체적 행위를 내가 만들어주기 귀찮기 때문이다.

그리고 오류도 뱉어주기 때문에 메서드 실수를 하지 않을 수 있다.

 

package ex11;

/**
 * 신입이 실수하지 않는 설계를 해보자!!
 * 신입이 실수하면 내 책임이니까!!
 */

// abstract class 추상 클래스
// 1. new 할 수 없다.
// 2. 추상 메서드를 만들 수 있다.(객체의 행위를 공통적으로 정의할 수 없을 때)
// 3. 추상 클래스는 일반 메서드도 만들 수 있다.(모든 구체적인 자식들의 공통적인 것)
abstract class ProtossUnit { // 종족 이름
    abstract int getHp();

    abstract int getAttack();

    abstract void setHp(int hp);
}

// 1. 일반 클래스는 추상 메서드를 가질 수 없다.
class Zealot extends ProtossUnit { // 근거리 공격
    // 상태 변수(heap에 저장)
    String name = "질럿"; // 원래는 값을 초기화하지 말고 생성자를 써야함
    int hp = 100;
    int attack = 10;

    @Override
    int getHp() {
        return hp;
    }

    @Override
    int getAttack() {
        return attack;
    }

    @Override
    void setHp(int hp) {
        this.hp = hp;
    }
}

class Dragoon extends ProtossUnit { // 원거리 공격
    String name = "드라군";
    int hp = 100;
    int attack = 20;

    @Override
    int getHp() {
        return hp;
    }

    @Override
    int getAttack() {
        return attack;
    }

    @Override
    void setHp(int hp) {
        this.hp = hp;
    }
}

class DarkTempler extends ProtossUnit {
    String name = "다크템플러";
    int hp = 100;
    int attack = 50;

    @Override
    int getHp() {
        return hp;
    }

    @Override
    int getAttack() {
        return attack;
    }

    @Override
    void setHp(int hp) {
        this.hp = hp;
    }
}

public class ExtendsEx04 {

    static void attack(ProtossUnit u1, ProtossUnit u2) {
        // 1. u1이 u2를 공격 => u2.hp = u2.hp - u1.attack => 자식 변수에 접근 안되는군 => 오버라이드 하자
        u2.setHp(u2.getHp() - u1.getAttack());
        // 2. u2의 hp를 출력 => sysout(u2.hp)
        System.out.println(u2.getHp());
    }

    public static void main(String[] args) {
        ProtossUnit 질럿 = new Zealot();
        ProtossUnit 드라군 = new Dragoon();
        ProtossUnit 다크템플러 = new DarkTempler();

        attack(질럿, 드라군);
        attack(다크템플러, 질럿);
    }
}

 

 

 

 

[출처]

 

https://cafe.naver.com/metacoding

 

메타코딩 : 네이버 카페

코린이들의 궁금증

cafe.naver.com

 

메타 코딩 유튜브

https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

 

메타코딩

문의사항 : getinthere@naver.com 인스타그램 : https://www.instagram.com/meta4pm 깃헙 : https://github.com/codingspecialist 유료강좌 : https://www.easyupclass.com

www.youtube.com

 

반응형