자바의 정석 요약
: 추상 클래스는 그 자체로 클래스로서의 역할을 다 하지 못한다. 하지만 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상 클래스로서 중요한 의미를 지닌다.
미완성 설계도는 완성된 제품을 만들수 없듯이, 추상 클래스 또한 인스턴스를 생성할 수 없다.
따라서 추상 클래스는 상속을 통해 자손클래스에 의해서 완성될 수 있다.
사용법
아래의 코드처럼 키워드 "abstrack"를 붙이기만 하면 된다.
abstract calss className {
...
}
추상 클래스는 추상 메서드를 포함하고 있다는 것을 제외하고 일반 클래스와 같다. 일반 클래스와 같이 생성자가 존재하고, 멤버변수와 메서드를 가질 수 있다.
: 메서드는 선언부와 구현부로 나누어져있는데, 추상 메서드는 선언부만 있는 것이다.
따라서 상속받은 클래스에서 메서드를 구현해야한다.
EX CODE
abstract class Player {
abstract void play(int pos);
abstract void stop();
}
class AudioPlayer extends Player {
void play(int pos) { /* ... */ } //추상메서드를 구현함.
void stop() { /* ... */ } //추상메서드를 구현함.
}
abstract class AbstractPlayer extends Player {
void play(int pos) { /* ... */ } //추상메서드를 구현함.
}
다음과 같이 AbstractPlayer클래스는 상속받은 추상클래스의 메서드중 일부만 구현했기 때문에, AbstractPlayer클래스도 추상클래스가 된다.
즉, 조상으로부터 상속받은 추상 메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해주어야한다.
EX CODE
abstract class Unit {
int x, y;
abstract void move(int x, int y);
void stop() {/* ... */ }
}
class Marine extends Unit {
void move(int x, int y) {/* ... */}
void strimPack() {/* ... */}
}
class Tank extends Unit {
void move(int x, int y) {/* ... */}
void changeMode() {/* ... */}
}
class Dropship extends Unit {
void move(int x, int y) {/* ... */}
void load() {/* ... */}
void unload() {/* ... */}
}
다음과 같이 클래스가 선언이 되었을 때, 아래의 코드처럼 활용이 가능하다.
Unit group - new Unit[4];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Marine();
group[3] = new Dropship();
for(int i = 0; i < group.length; i++)
group[i].move(100,200);
Unit에 move 메서드가 있기 때문에 "group[i].move(100,200)"이 가능한 것이다.
Unit클래스에 move 메서드가 추상메서드로 정의되어 있다고 하지만, 실제로 move 메서드가 호출될 때에는 참조변수의 타입에 관계없이 실제로 인스턴스에서 구현된 것이 호출된다.
만약에 move메서드가 없는 Object 클래스를 호출하게 되면 move메서드를 호출하는 부분에서 에러가 난다.