// 미완성 설계도. 추상메서드(미완성 메서드)를 가지고 있는 클래스
abstract class Player {
abstract void play(int pos); // 추상 메서드(몸통{}이 없는 미완성 메서드)
abstract void stop(); // 추상 메서드
}
다른 클래스 작성에 도움을 주기 위한 것.인스턴스 생성불가
// 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상 클래스. 인스턴스 생성 불가
Player p = new Player(); // 에러. 추상 클래스의 인스턴스 생성 '불가'
상속을 통해 추상메서드를 완성해야 인스턴스 생성 가능
// 상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능
class AudioPlayer extends Player {
void play(int pos) { /* 내용 생략 */ } // 추상메서드를 구현
void stop() { /* 내용 생략 */ } // 추상메서드를 구현
}
AudioPlayer ap = new AudioPlayer(); // OK. 인스턴스 생성 '가능'
/*
Player ap = new AudioPlayer(); // OK. 다형성
*/
상속받은 추상메서드를 모두 구현하지 않은 경우, 자손 클래스 선언부 앞에abstract를 붙여야 한다.
abstact class Player { // 추상클래스
abstract void play(int pos); // 추상메서드
abstract void stop(); // 추상메서드
void play() { // 인스턴스 메서드
play(currentPos); // 추상메서드를 사용할 수 있다.
}
} // 메서드는 선언부만 알면 호출가능하므로 추상메서드도 호출 가능하다.
class AudioPlayer extends Player {
void play(int pos) { /* 내용 생략 */ } // 추상메서드를 구현
void stop() { /* 내용 생략 */ } // 추상메서드를 구현
}
abstract class AbstractPlayer extends Player { // 추상메서드 1개만 구현(미완성)
void play(int pos) { /* 내용 생략 */ } // 추상메서드를 구현
} // abstract void stop(); 이 생략됨
/*
추상메서드 구현 : 몸통({}) 만들어주기
*/
im : 추상 메서드 호출 가능(호출할 때는 선언부만 필요하기 때문)
추상메서드 호출 조건
상속을 통해 자손이 완성
자손 객체 생성
인스턴스메서드는 객체 생성 후 호출 가능하다.
하지만, 지금은 추상클래스이기 때문에 객체 생성이 불가하다.
따라서, 지금은 추상클래스의 인스턴스메서드에 호출하는 코드가 있어도 호출할 수 없다.
상속을 통해 자손이 추상메서드를 구현한 후,자손 객체 생성 후추상메서드를 호출할 수 있게 된다.
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); // 추상메서드를 사용할 수 있다.
}
}
abstract class Player {
abstract void player(int pos); // 추상메서드(미완성 메서드)
abstract void stop(); // 추상메서드(선언부만 있고 구현부{}가 없는 메서드)
}
// 추상 클래스는 상속을 통해 완성해야 객체 생성 가능
class AudioPlayer extends Player {
void player(int pos) { System.out.println(pos + "위치부터 play합니다.");}
void stop() { System.out.println("재생을 멈춥니다.");}
}
public class PlayerTest {
public static void main(String[] args) {
// Player p = new Player(); // 추상클래스의 객체를 생성
// AudioPlayer ap = new AudioPlayer();
Player ap = new AudioPlayer(); /// 다형성
ap.player(100);
ap.stop();
}
}
리모컨이 아무리 추상메서드라고 해도 실제로 구현된 메서드가 실행된다.
Player타입의 참조변수가 메서드를 호출하면 실제 객체의 play메서드가 호출된다.
리모컨 타입에는 선언문만 있으면 된다.
다형성
추상클래스의 작성
여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성하거나, 기존클래스의 공통 부분을 뽑아서 추상클래스를 만든다.
모든 클래스의 조상인 Object클래스 타입의 배열로도 서로 다른 종류의 인스턴스를 하나의 묶음으로 다룰 수 있다. 하지만, Object클래스에는 move메서드가 정의되어 있지 않기 때문에 move메서드를 호출하는 부분에서 에러가 발생한다.
Object[] group = new Object[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Dropship();
for(int i = 0; i < group.length; i++)
group[i].move(100, 200) // 에러!!!! Object클래스에 move메서드가 정의되어 있지 않다.