자기 개발/Java

자바 추상클래스

SeungHwa 2013. 9. 5. 13:20
추상클래스(Abstract calss)

추상클래스란? 

클래스를 설계도로 비유한다면, 추상클래스는 미완성 설계도에 비유할 수 있다. 미완성 설계도란 , 단어의 뜻 그대로 완성되지 못한 체로 남겨진 설계도를 말한다.

클래스가 미완성이라는 것은 멤버의 개수에 관계된 것이 아니라 ,  단지 미완성 메서드(추상메서드) 를 포함하고 있다는 의미이다.

추상클래스는 키워드 'abstract'를 붙이기만 하면 된다. 이렇게 함으로 이 클래스를 사용할 때 , 클래스 선언부의 abstract를 보고 이 클래스에는 추상 메서드가 있으니 상속을 통해 구현해 주어야한다는 것을 알수있다.


abstract calss 클래스이름 {
     //....
}

* 추상메서드를 포함하고 있지 않은 클래스에도 키워드 'abstract'를 붙여서 추상클래스로 지정할 수도 있다. 추상메서드가 없는 완성된 클래스라 할지라도 추상클래스로 지정되면 클래스의 인스턴스를 생성할 수 없다.


추상메서드(abstract 메서드)


메서드는 선언부와 구현부(몸통)로 구성되어 있다 . 하지만 추상메서드는 선언부만 작성하고 , 구현부는 작성하지 않은 체로 남겨 둔것이 추상메서드이다. 즉 , 설계만 해 놓고 실제 수행될 내용은 작성하지 않기 때문에 미완성 메서드 인 것이다.

메서드를 이와 같이 미완성 상태로 남겨 놓은 이유는 메서드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문에 조상클래스에서는 선언부만을 작성하고, 주석을 덧붙여 어떤 기능을 수행할 목적으로 작성되었는지 알려 주고 , 실제 내용은 상속받은 클래스에서 구현하도록 비워 두는 것이다.

추상메서드 역시 키워드'abstract'를 앞에 붙여 주고 , 추상메서드는 구현부가 없으므로 괄호{}대신 문장의 끝을 알리는 ';' 을 적어준다.

abstract 리턴타입 메서드이름();


추상클래스로 부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메서드를 모두 구현해주어야 한다. 만일 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해 주어야한다. 

추상클래스의 작성

여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성하기도 하고 , 기존의 클래스의 공통적인 부분을 뽑아서 추상클래스로 만들어 상속하도록 하는 경우도 있다. 

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

추상화 - 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업 
구체화 - 상속을 통해 클래스를 구현 , 확장하는 작업

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

      Player() {                   // 추상클래스도 생성자가 있다.
            pause = false;
            currentPos = 0;
      }
/** 지정된 위치(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를 한다.
            } else {                   // pause가 false일 때(play상태)에서 pause가 호출되면,
                  pause = true;             // pause의 상태를 true로 바꾸고
                  stop();                   // play를 멈춘다.
            }
      }
}