프로그래밍 언어/Java

[JAVA] 추상클래스 abstract class

반응형

추상[抽象]?

낱낱의 구체적 표상이나 개념에서 공통된 성질을 뽑아 이를 일반적인 개념으로 파악하는 정신 작용

 

상속은 자손 클래스를 만드는데 조상 클래스를 사용하는것이라면, 이와 반대로 추상화는 기존의 클래스의 공통부분을 뽑아내서 조상 클래스를 만드는 것이라고 할 수 있다.

 

추상클래스?

클래스 = 설계도

추상클래스 = 미완성설계도 (완성되지 못한 채로 남겨진 설계도)

 

인스턴스 생성 불가능

상속을 통해서 자손클래스에 의해서만 완성될 수 있다.

 

일반 클래스와 차이점?

추상클래스는 추상메서드를 포함하고 있다는 것을 제외하고는 일반클래스와 전혀 다르지 않다.

추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수있다.

 

public class Main {
    public static void main(String[] args) {
        CDPlayer cdPlayer = new CDPlayer();
        
        cdPlayer.pause = true;
        cdPlayer.pause();

        cdPlayer.pause = false;
        cdPlayer.pause();
    }
}

abstract class Player{
    boolean pause;  //일시정지 상태를 저장하기 위한 변수
    int currentPos; //현재 Play되고 있는 위치를 저장하기 위한 변수

    Player(){   //추상클래스도 생성자가 있어야 한다.
        pause = false;  //일시정지 상태를 저장하기 위한 변수
        currentPos = 0; //현재 Play되고 있는 위치를 저장하기 위한 변수
    }

    //지정된 위치(pos)에서 재생을 시작하는 기능이 수행하도록 작성되어야 한다.
    abstract void play(int pos);

    //재생을 즉시 멈추는 기능을 수행하도록 작성되어야 한다.
    abstract void stop();

    void play(){
        play(currentPos);
    }

    void pause(){
        if(pause){  //pause가 true일 때 (정지상태)에서 pause가 호출되면,
            pause = false;  //pause의 상태를 false로 변경
            play(currentPos);   //현재의 위치에서 play를 한다.
            System.out.println("pause -> play");
        } else {    //pause가 false일 때 pause가 호출되면,
            pause = true;   //pause상태를 true로 바꾸고
            stop(); //play를 멈춘다.
            System.out.println("play -> pause");
        }
    }
}

class CDPlayer extends Player{
    int currentTrack;

    //CDPlayer만의 새로운 기능1
    void nextTrack(){
        currentTrack++;
    }

    //CDPlayer만의 새로운 기능2
    void preTrack(){
        if(currentTrack > 1){
            currentTrack--;
        }
    }

    @Override
    void play(int pos) {
        /*조상의 추상메서드를 구현해야 한다.*/
    }

    @Override
    void stop() {
        /*조상의 추상메서드를 구현해야 한다.*/
    }
}

굳이 abstract를 붙여서 추상메서드로 선언하는 이유는 자손 클래스에서 추상메서드를 반드시 구현하도록 강요하기 위해서다. 만일 추상메서드로 정의되어 있지 않고, 빈 몸통만 가지도록 정의되어 있다면, 상속받는 자손 클래스에서는 이 메서드들이 온전히 구현된 것으로 인식하고 오버라이딩을 통해 자신의 클래스에 맞도록 구현하지 않을 수도 있기 떄문이다.

하지만 abstract를 사용해서 추상메서드로 정의해놓으면, 자손 클래스를 작성할 때 이들이 추상메서드이므로 내용을 구현해주어야 한다는 사실을 인식하고 자신의 클래스에 알맞게 구현해야 한다.

반응형