Sam Story

JAVA - 추상클래스 본문

JAVA

JAVA - 추상클래스

Sam H 2024. 11. 21. 16:47

 

오늘은 추상클래스에 대해서 포스팅 하려한다.

지난번 객체지향 프로그래밍의 특징에 대해서 포스팅할 때

추상화에 대해서 간단하게 다루어 봤지만

오늘은 예제를 보며 어떤식으로 사용할지에 대해서 다루어 보도록 하겠다.

 

 

추상화 란?

추상이라는 용어의 사전적 의미를 보면“사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것”여기서 핵심이 되는 개념은 “공통성과 본질을 모아 추출”한다는 것

 

객체 지향 프로그래밍에서 의미하는 추상화는 객체의 공통적인 속성과 기능을 추출하여 정의하는것을 의미

인터페이스에는 추상 메서드나 상수를 통해서 어떤 객체가 수행해야 하는 핵심적인 역할만을 규정해두고, 

실제적인 구현은 해당 인터페이스를 구현하는 각각의 객체들에서 하도록 프로그램을 설계하는 것을 의미

 

클래스를 설계도라 하면, 추상 클래스는 미완성 설계도에 비유할 수 있다.

 

간단히 정리하자면

 

1.추상클래스는 하위 클래스들의 공통점들을 모아 추상화하여 만든 클래스

2.추상클래스는 다중 상속이 불가능하여 단일 상속만 허용

3.추상클래스는 추상 메소드 외에 일반클래스와 같이 일반적인 필드변수, 메서드, 생성자를 가진다

4.이러한 특징으로, 추상클래스는 추상화(추상 메서드)를 하면서 중복되는 클래스 요소들을 통합 및 확장 가능.

 

 

간단히 예시를 보며 쉽게 알아보자.

 

전사 class 와 마법사 class를 구현하고 보니

체력 마나 힘 민첩 등 고유한 능력치는 서로 같은 내용을 공유한다.

 

이러한 경우처럼 공통한 변수, 메서드 등이 많은 경우 추상클래스를 이용해서

상위클래스를 구현하고 이를 상속하여 사용하는게 다른 종류의 직업들을 구현함에 있어

훨씬 유연하게 설계를 할 수 있다는 것이다.

 

추상 클래스를 이용해 구현하게 되면

위 그림처럼 새로운 상위 클래스를 추상클래스로 만들어서

공통된 속성들을 작성하는게 아닌 틀을 만들어 준다.

 

이렇게 작성해주고 전사 class,마법사 class 가 상속을 받고

필요한 내용을 추가로 작성해 주면 기존 코드와 같은 동작을 하게되고

새로운 직업들을 구현한다고 했을 때 확장성 또한 굉장히 유연하게 된다.

 

 

코드를 보면서 좀 더 직관적으로 보게되면

 

Warrior class , Wizard class

// 전사 class
public class Warrior {

    int hp;
    int mp;
    int str;
    int dex;
    int wis;
    int luck;

    void skill() {
        System.out.println("전사는 강타를 사용했다.");
    }
    void useItem() {
        System.out.println("전사는 아이템을 사용했다.");
    }

    // 전사 고유능력 도발
    void taunt() {
        System.out.println("전사는 도발을 사용했다.");
    }
}

// 마법사 class
public class Wizard {

    int hp;
    int mp;
    int str;
    int dex;
    int wis;
    int luck;

    void skill() {
        System.out.println("마법사는 파이어볼을 사용했다.");
    }
    void useItem() {
        System.out.println("마법사는 아이템을 사용했다.");
    }

    // 마법사 고유능력 텔레포트
    void teleport() {
        System.out.println("마법사는 텔레포트를 사용했다.");
    }
}

 

기존 전사 class 와 마법사 class를 정의하여 작성한다면 위처럼 작성할 수 있을것이다.

 

이러한 class를 추상class를 이용하여 작성하게 되면.

 

User class

public abstract class User {
    int hp;
    int mp;
    int str;
    int dex;
    int wis;
    int luck;

    abstract void skill();
    abstract void useItem();
}

 

공통되는 속성의 변수들을 선언해주고,

공통적으로 사용되는 메서드들을 abstract 메서드로 선언해준다.

 

이처럼 User라는 상위클래스를 추상 클래스로 구현해준다.

이 class를 상속받는 새로운 전사 class 와 마법사 class를 작성하면

 

아래처럼 작성할 수 있다.

 

Warrior class , Wizard class

public class Warrior extends User{
    @Override
    void skill() {
        System.out.println("전사는 강타를 사용했다.");
    }

    @Override
    void useItem() {
        System.out.println("전사는 아이템을 사용했다.");
    }

    void taunt() {
        System.out.println("전사는 도발을 사용했다.");
    }
}

public class Wizard extends User{
    @Override
    void skill() {
        System.out.println("마법사는 파이어볼을 사용했다.");
    }

    @Override
    void useItem() {
        System.out.println("마법사는 아이템을 사용했다.");
    }

    void teleport() {
        System.out.println("마법사는 텔레포트를 사용했다.");
    }
}

 

 

사실 공통된 필드와 메서드를 통일하는 목적으로는 일반 클래스로도 가능하여 

꼭 추상 클래스만의 고유 용도라고는 보기에는 힘들다. 

 

그렇다면 왜 이러한 코드에서 추상클래스를 사용하는가?

 

1. 공통 속성과 메서드 정의

- 공통되는 속성과 메서드를 추상클래스에 정의함으로써 코드 중복을 방지한다.

 

2. 직업별로 행동을 강제

- 추상 클래스는 추상 메서드를 통해 하위 클래스에서 반드시 특정 메서드를 구현하도록 강제한다.

- 이를 일반 클래스에서 구현하면, 고유한 메서드를 실수로 빼먹거나 잘못 정의할 가능성이 높아진다.

 

3. 추상 클래스는 인스턴스화 불가

- User 객체는 직접 사용할 객체가 아니라, 전사(Warrior)와 마법사(Wizard) 같은 구체적인 클래스만 사용하기 때문
- 추상 클래스로 선언하면 실수로 User 자체를 인스턴스화하는 일을 막을 수 있다.

User user = new User(); // 컴파일 에러 발생!

 

- 이는 로직에서 "User는 항상 전사(Warrior), 마법사(Wizard) 등 구체적인 직업이어야 한다"는 규칙을 강제한다

 

 

 

이렇게 추상클래스에 대해서 간단히 알아보았다.

추상 클래스는 공통된 특성을 가진 객체를 모델링할 때 적합하고,

행동을 강제하면서 코드의 재사용성과 안정성을 높이는 데 적합하다.


물론, 모든 경우에 추상 클래스를 써야 하는 것은 아니며,

필요에 따라 일반 클래스를 사용하는 것이 더 간단할 수 있다.

하지만 위처럼 명확한 역할과 강제 구현이 필요할 경우 추상 클래스가 좋은 선택이 될 수 있다.

'JAVA' 카테고리의 다른 글

JAVA - Stack  (1) 2024.11.30
JAVA - 인터페이스  (2) 2024.11.22
JAVA - 의존 역전 원칙  (2) 2024.10.20
JAVA - 인터페이스 분리 원칙  (1) 2024.10.16
JAVA - 리스코프 치환 원칙  (0) 2024.10.15